[英]How can for i in ${VAR} ever work in bash, instead of for i in "${VAR[@]}"?
If I try on my machine (with bash 3,4 and 5) the following command:如果我在我的机器上(使用 bash 3,4 和 5)尝试以下命令:
bash-5.0$ VAR=(1 2 3)
bash-5.0$ for i in ${VAR}; do echo $i; done
I get only one line with the 1
.我只得到一行
1
。
If I do the same on ZSH for example, it nicely writes the three lines with progressive numbers.例如,如果我在 ZSH 上做同样的事情,它会用渐进数字很好地写出三行。
However in one of our production servers I found this:但是,在我们的其中一台生产服务器中,我发现了这一点:
bash -c "for i in ${MY_VAR}; do stuff with $i; done"
And by checking the logs it seems that it is actually iterating correctly!通过检查日志,它似乎实际上是在正确地迭代!
How is this possible?这怎么可能? Is it a particular version of bash I'm not aware of?
它是我不知道的特定版本的 bash 吗? Or some flag I should set?
或者我应该设置一些标志? Or maybe the array was populated in a particular way?
或者数组可能以特定方式填充?
You should write:你应该写:
var=(1 2 3)
for i in "${var[@]}"; do
do stuff with "$i"
done
You need [@]
as shown.如图所示,您需要
[@]
。 And don't use uppercase variable names.并且不要使用大写的变量名。 Now as to why it works on your production server: possibly because
MY_VAR
is defined as MY_VAR="1 2 3"
(or something analogous), ie, MY_VAR
isn't an array (which is bad).现在至于为什么它在您的生产服务器上工作:可能是因为
MY_VAR
被定义为MY_VAR="1 2 3"
(或类似的东西),即MY_VAR
不是一个数组(这很糟糕)。
It "works" because the code isn't actually using an array at all.它“有效”,因为代码实际上根本没有使用数组。
export MY_VAR='1 2 3'
bash -c 'for i in ${MY_VAR}; do echo "Doing stuff with $i"; done'
...involves no arrays whatsoever; ...不涉及任何数组;
MY_VAR
is a string being word-split and then glob-expanded. MY_VAR
是一个分词然后全局扩展的字符串。
Don't do that, ever , even if you really do need to iterate over items from a delimiter-separated string.永远不要这样做,即使您确实需要从分隔符分隔的字符串中迭代项目。 The reliable alternative is to use
read -r -a my_array <<<"$MY_VAR"
to read your string into an array, and then for i in "${my_array[@]}"; do echo "Doing stuff with $i"; done
可靠的替代方法是使用
read -r -a my_array <<<"$MY_VAR"
将您的字符串读入数组,然后for i in "${my_array[@]}"; do echo "Doing stuff with $i"; done
for i in "${my_array[@]}"; do echo "Doing stuff with $i"; done
for i in "${my_array[@]}"; do echo "Doing stuff with $i"; done
to iterate over it. for i in "${my_array[@]}"; do echo "Doing stuff with $i"; done
迭代它。
Looks like Bash evaluates $arr
to ${arr[0]}
:看起来 Bash 将
$arr
评估$arr
${arr[0]}
:
arr=(1 2 3)
echo $arr # yields 1
arr[0]=999
echo $arr # yields 999
With associative arrays:使用关联数组:
declare -A h
h=([one]=1 [two]=2)
echo $h # yields nothing
h=([0]=1 [two]=2)
echo $h # yields 1
As others have pointed out, the right way to loop through an array is:正如其他人所指出的,循环数组的正确方法是:
for i in "${arr[@]}"; do ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.