Косвенная адресация это когда, грубо говоря, одна переменная ссылается на какое-либо значение через другую переменную. Если говорить точнее и применительно к bash'у, то это когда одна переменная хранит имя другой переменной, которая в свою очередь содержит, например, какое-либо значение. С помощью косвенной адресации можно, используя первую переменную, сразу получить доступ к значению, которое содержит вторая переменная. Как это работает вроде бы ясно, но, возможно, не сразу понятна нужность всего этого.
Итак, допустим у нас есть переменная X, которая содержит строку "значение". Так же есть переменная Y, которая в качестве значения содержит имя переменной X. Красивость заключается в том, что с помощью прямой и косвенной адресации, используя переменную Y, можно получить соответственно имя и значение переменной X.
Простой пример:
Теперь приведу более жизненный пример. У меня есть скрипт, который настраивает iptables. Косвенная адресация в нем используется для того, чтобы сделать проще изменение настроек скрипта и создать красивый вывод. Приведу пример поясняющий основную суть.
Таким образом, для настройки скрипта в переменной INPUT_PORTS_ACCEPT нужно указывать не номера портов, а просто имена сервисов, и в выводе наглядно показано на какие локальные сервисы открыт доступ и какие порты им соответствуют. Красиво :)
Итак, допустим у нас есть переменная X, которая содержит строку "значение". Так же есть переменная Y, которая в качестве значения содержит имя переменной X. Красивость заключается в том, что с помощью прямой и косвенной адресации, используя переменную Y, можно получить соответственно имя и значение переменной X.
Простой пример:
X="значение" Y=X echo "$Y: ${!Y}"В этом примере с помощью прямой адресации $Y мы получаем доступ к имени переменной X, а с помощью косвенной ${!Y} - к её значению. В старых версиях bash косвенная адресация могла использоваться только так eval Z=\$$Y, а начиная со 2 версии она стала выглядеть проще, хотя старый вариант так же может использоваться.
Теперь приведу более жизненный пример. У меня есть скрипт, который настраивает iptables. Косвенная адресация в нем используется для того, чтобы сделать проще изменение настроек скрипта и создать красивый вывод. Приведу пример поясняющий основную суть.
#!/bin/bash # список сервисов и их портов SSH=22 HTTP=80 HTTPS=443 SAMBA="137 138 139 445" # локальные сервисы на которые разрешен доступ снаружи INPUT_PORTS_ACCEPT="SSH SAMBA HTTP HTTPS" echo "Удаленный доступ к сервисам хоста:" # открываем доступ на разрешенные сервисы for SERVICE_NAME in $INPUT_PORTS_ACCEPT do # для каждого порта сервиса добавляем разрешающие правила в iptables PORTS=${!SERVICE_NAME} # устаревший вариант: eval PORTS=\$$SERVICE_NAME for PORT in $PORTS do iptables -t filter -A INPUT -i eth0 -p tcp --dport $PORT -j ACCEPT iptables -t filter -A INPUT -i eth0 -p udp --dport $PORT -j ACCEPT done # выводим имя и порты сервиса echo "$SERVICE_NAME: $PORTS --accept" doneВывод скрипта:
Удаленный доступ к сервисам хоста:
SSH: 22 --accept
SAMBA: 137 138 139 445 --accept
HTTP: 80 --accept
HTTPS: 443 --accept
Таким образом, для настройки скрипта в переменной INPUT_PORTS_ACCEPT нужно указывать не номера портов, а просто имена сервисов, и в выводе наглядно показано на какие локальные сервисы открыт доступ и какие порты им соответствуют. Красиво :)
Как на счет Bash'евских ассоциатывных массивов? Так:
ОтветитьУдалитьdeclare -A arr
arr[HTTP]='80 443'
arr[SSH]=22
for i in ${!arr[@]}; do echo $i = ${arr[$i]}; done
Главное что ключи будут спрятаны в пространстве имен arr ))