简体   繁体   English

for i in ${VAR} 如何在 bash 中工作,而不是 for i in "${VAR[@]}"?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM