Я пишу bash-скрипт для использования rsync и обновления файлов примерно на 20 разных серверах.
Я разобрался с частью Rsync. У меня проблемы с просмотром списка переменных.
Мой сценарий до сих пор выглядит так:
#!/bin/bash
SERVER1="192.xxx.xxx.2"
SERVER2="192.xxx.xxx.3"
SERVER3="192.xxx.xxx.4"
SERVER4="192.xxx.xxx.5"
SERVER5="192.xxx.xxx.6"
SERVER6="192.xxx.xxx.7"
for ((i=1; i<7; i++))
do
echo [Server IP Address]
done
Где [Server IP Address]
должно быть значение связанной переменной. Поэтому, когда я = 1, я должен повторить значение $ SERVER1.
Я пробовал несколько итераций этого, в том числе
echo "$SERVER$i" # printed the value of i
echo "SERVER$i" # printer "SERVER" plus the value of i ex: SERVER 1 where i = 1
echo $("SERVER$i") # produced an error SERVER1: command not found where i = 1
echo $$SERVER$i # printed a four digit number followed by "SERVER" plus the value of i
echo \$$SERVER$i # printed "$" plus the value of i
Прошло много времени с тех пор, как я написал сценарий, поэтому я знаю, что что-то упустил. Кроме того, я уверен, что я смешиваю то, что я мог сделать, используя C #, который я использовал в течение последних 11 лет.
Возможно ли то, что я пытаюсь сделать? Или я должен положить эти значения в массиве и цикл по массиву? Мне нужно то же самое для производственных IP-адресов, а также имен местоположений.
Это все для того, чтобы не повторять блок кода, который я буду использовать для синхронизации файлов на удаленном сервере.
источник
Ответы:
Используйте массив.
источник
Как указывают другие ответы, массив является наиболее удобным способом сделать это. Однако, для полноты, именно то, о чем вы просите, - это косвенное расширение . Переписав, ваш образец также будет работать с использованием этого метода:
Если вы согласны с тем, что поместили список IP-адресов в
for
цикл, вы можете также рассмотреть возможность использования некоторых расширений скобок для перебора всего, что вам нужно:Но если вам нужно повторно использовать список (возможно, с расширенными скобками), то использование этого списка для инициализации массива будет правильным способом:
источник
Хотя я, вероятно, сам пойду с одним из ответов в массиве, я хотел бы отметить, что можно зацикливать имена напрямую. Ты можешь сделать
или, в 4.3 и выше, вы можете использовать
nameref
:Наконечник шляпы ilkkachu для решения <4.3.
источник
${!var}
) также работает со старыми версиями Bash:foo1=aa; foo2=bbb; foox=cccc; for p in "${!foo@}"; do echo "$p = ${!p}"; done
Каждый, кто сказал, что вы должны использовать массив, является правильным, но - в качестве академического упражнения - если вы решили сделать это с отдельными переменными, заканчивающимися на число (SERVER1, SERVER2 и т. Д.), Это то, что вы должны делать Это:
источник
eval
трудно безопасно использовать. Да, это может работать, но косвенное расширение bash является лучшим способом в целом.eval
как сделано, у васecho $SERVER1
нетecho "$SERVER1"
. Да, можно использовать безопасно, но очень просто или небезопасно, как вы и предполагали!