Bash数组声明与赋值异常问题求助:为何循环中输出结果不符合预期?
问题根源:旧版本bash不支持关联数组
兄弟,你的问题完全是因为用了macOS自带的旧版bash(3.2.57)!这个版本的bash根本不支持关联数组(就是用字符串当索引的数组),这才导致了看起来奇怪的行为。
具体原因拆解:
- 当你用
declare -A object想声明关联数组时,bash 3.2会直接忽略这个指令——它根本不认-A选项!所以object本质还是普通的索引数组,只能用整数当索引。 - 当你尝试用
"a"、"b"、"c"这种字符串作为索引赋值时,bash会把这些非数字字符串强制转换成整数。转换失败的话,就默认用0作为索引。也就是说:object["a"]="${arr[1]}"→ 实际是给object[0]赋值xobject["b"]="${arr[2]}"→ 直接覆盖object[0]的值为yobject["c"]="${arr[3]}"→ 再次覆盖object[0]的值为z
- 你的循环会跑3次(因为
${arr[@]}展开成了x y z三个元素),每次循环最后object[0]都会被最终覆盖成z,所以你看到的输出就是z。 - 当你注释掉后面两行赋值时,
object[0]只会被赋值一次x,循环三次每次输出的都是x,自然符合预期。
解决方案:
方案1:升级bash(推荐)
macOS自带的bash版本太老了,直接用Homebrew装个新版的:
brew install bash
安装完成后,用bash --version确认版本在4.0以上,这时候declare -A就能正常创建关联数组了,字符串索引会被正确识别,不会再被强制转成0,你的代码就能按预期运行。
方案2:不升级,改用整数索引
如果不想升级,就把object改成普通索引数组,用数字当索引:
declare -a object for var in ${arr[@]} do object[0]="${arr[1]}" object[1]="${arr[2]}" object[2]="${arr[3]}" echo ${object[0]} done
这样object[0]的值就不会被后面的赋值覆盖,输出就是x。
额外小建议:
你的循环逻辑有点冗余——每次循环里的赋值都是一模一样的,完全可以把赋值语句放到循环外面,避免重复执行:
# bash 4+ 版本用这个 declare -A object object["a"]="${arr[1]}" object["b"]="${arr[2]}" object["c"]="${arr[3]}" for var in ${arr[@]} do echo ${object["a"]} done
内容的提问来源于stack exchange,提问作者YYZZYY
相关产品推荐
相关产品推荐

