我在 bash 中的数组方面遇到了一些问题。
给定这个数组:
krn=(linux-image-4.15.0-30-generic linux-image-4.15.0-32-generic linux-image-4.15.0-33-generic)
如果我使用以下 for 循环来迭代它,我会得到不同的结果而不更改任何内容:
第一次:
for krn in ${krn[@]};do echo $krn;done
linux-image-4.15.0-30-generic
linux-image-4.15.0-32-generic
linux-image-4.15.0-33-generic
第二次:
for krn in ${krn[@]};do echo $krn;done
linux-image-4.15.0-33-generic
linux-image-4.15.0-32-generic
linux-image-4.15.0-33-generic
我究竟做错了什么?
如果我使用 C 风格的数组长度,它就不会出现这种奇怪的行为。
for ((i=0; i<${#krn[@]}; i++)); do echo ${krn[i]};done
答案1
您的循环用作krn
循环变量。这也是您循环的数组的名称。 shell 不为数组变量和非数组变量维护单独的名称空间。
对于每次迭代,krn
将设置为数组中的当前值。这具有在每次迭代中修改数组的第一个元素的效果。循环修改数组,以便第一个元素将是循环结束后最后一个元素的副本。
要纠正此问题,请为循环变量或数组选择另一个名称。
此外,您应该"${krn[@]}"
在循环头中使用(扩展,双引号),因为使用${krn[@]}
不带引号会在空格(或 中的任何内容$IFS
)上拆分每个元素,并在结果单词上调用文件名通配。echo "${krn[i]}"
在后面的循环中也是如此。
假设数组中至少有一个元素,则整个循环也可以替换为
printf '%s\n' "${krn[@]}"