Как может я в $ {VAR} когда-либо работать в bash, а не я в "$ {VAR [@]}"? - PullRequest
0 голосов
/ 21 января 2019

Если я попробую на своей машине (с bash 3,4 и 5) следующую команду:

bash-5.0$ VAR=(1 2 3)
bash-5.0$ for i in ${VAR}; do echo $i; done

Я получу только одну строку с 1.

Если ясделайте то же самое на ZSH, например, он хорошо записывает три строки с прогрессивными числами.

Однако на одном из наших производственных серверов я нашел это:

bash -c "for i in ${MY_VAR}; do stuff with $i; done"

И, проверив его логиКажется, что это на самом деле итерация правильно!

Как это возможно?Это какая-то конкретная версия bash, о которой я не знаю?Или какой-то флаг, который я должен установить?Или, может быть, массив был заполнен определенным образом?

Ответы [ 3 ]

0 голосов
/ 21 января 2019

Это "работает", потому что код на самом деле вообще не использует массив.

export MY_VAR='1 2 3'
bash -c 'for i in ${MY_VAR}; do echo "Doing stuff with $i"; done'

... не содержит никаких массивов; MY_VAR - это строка, разбитая на слова, а затем расширяемая глобусом.

Не делайте этого, когда-либо , даже если вам действительно нужно перебирать элементы из строки, разделенной разделителем. Надежной альтернативой является использование read -r -a my_array <<<"$MY_VAR" для чтения вашей строки в массив, а затем for i in "${my_array[@]}"; do echo "Doing stuff with $i"; done для ее итерации.

0 голосов
/ 24 января 2019

Похоже, Bash оценивает $arr до ${arr[0]}:

arr=(1 2 3)
echo $arr      # yields 1

arr[0]=999
echo $arr      # yields 999

С ассоциативными массивами:

declare -A h
h=([one]=1 [two]=2)
echo $h            # yields nothing

h=([0]=1 [two]=2)
echo $h            # yields 1

Как уже отмечали другие, правильный способ перебрать массив:

for i in "${arr[@]}"; do ...
0 голосов
/ 21 января 2019

Вы должны написать:

var=(1 2 3)
for i in "${var[@]}"; do
    do stuff with "$i"
done

Вам нужно [@], как показано. И не используйте имена переменных в верхнем регистре. Теперь о том, почему он работает на вашем производственном сервере: возможно, потому что MY_VAR определяется как MY_VAR="1 2 3" (или что-то аналогичное), то есть MY_VAR не является массивом (что плохо).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...