Shell中同名变量的嵌套for循环不符合预期的原因
Shell嵌套for循环变量名冲突的异常分析
错误代码
i=(0.0001 0.00001 0.000001) j=(0.5 0.6 0.7) for i in "${i[@]}" do for j in "${j[@]}" do echo "meta: $i, inner: $j" done done
实际输出
meta: 0.0001, inner: 0.5 meta: 0.0001, inner: 0.6 meta: 0.0001, inner: 0.7 meta: 0.00001, inner: 0.7 meta: 0.00001, inner: 0.6 meta: 0.00001, inner: 0.7 meta: 0.000001, inner: 0.7 meta: 0.000001, inner: 0.6 meta: 0.000001, inner: 0.7
预期输出
meta: 0.0001, inner: 0.5 meta: 0.0001, inner: 0.6 meta: 0.0001, inner: 0.7 meta: 0.00001, inner: 0.5 meta: 0.00001, inner: 0.6 meta: 0.00001, inner: 0.7 meta: 0.000001, inner: 0.5 meta: 0.000001, inner: 0.6 meta: 0.000001, inner: 0.7
异常原因
在Bash中,普通变量和数组变量共享同一个命名空间:普通变量j本质就是数组j的第0个元素${j[0]}。当你用数组名j作为内层循环的变量时,每次循环给j赋值都会直接修改数组j的第0个元素,导致后续遍历数组j时迭代列表发生变化。
具体执行逻辑
- 初始化阶段:定义数组
i(元素为0.0001、0.00001、0.000001)和数组j(元素为0.5、0.6、0.7),此时普通变量j等价于${j[0]},值为0.5。 - 外层第一次循环:
- 外层循环迭代列表
"${i[@]}"在启动时一次性展开为数组i的三个元素,第一次给变量i赋值0.0001。 - 内层循环遍历数组
j,依次给变量j赋值0.5、0.6、0.7——每一次赋值都会修改数组j的第0个元素。 - 内层循环结束后,数组
j的元素变为0.7、0.6、0.7(第0个元素被最后一次赋值的0.7覆盖)。
- 外层循环迭代列表
- 外层第二次、第三次循环:
- 外层循环继续给
i赋值0.00001、0.000001。 - 内层循环遍历的数组
j已经被修改,迭代列表变为0.7、0.6、0.7,因此输出不符合预期。
- 外层循环继续给
解决办法
将数组名和循环变量名区分开,避免命名冲突,比如用i_ls、j_ls作为数组名:
i_ls=(0.0001 0.00001 0.000001) j_ls=(0.5 0.6 0.7) for i in "${i_ls[@]}" do for j in "${j_ls[@]}" do echo "meta: $i, inner: $j" done done
内容的提问来源于stack exchange,提问作者tony
相关产品推荐
相关产品推荐

