如果我尝试使用我的机器(使用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吗?或者我应该设置一些旗帜?或者阵列可能以特定方式填充?
它“有效”,因为代码实际上根本没有使用数组。
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
迭代它。
你应该写:
var=(1 2 3)
for i in "${var[@]}"; do
do stuff with "$i"
done
你需要[@]
如图所示。并且不要使用大写变量名。现在,为什么它在您的生产服务器上工作:可能因为MY_VAR
被定义为MY_VAR="1 2 3"
(或类似的东西),即MY_VAR
不是一个数组(这是坏的)。
看起来像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 ...