Bash动态获取数组变量报错:${subarr$count[1]}非法替换求解
问题:Bash动态数组访问报错处理
问题场景
定义数组并通过循环动态创建子数组:
arr=('(appsettings.Dev.json 'up_np:@' 'up_np:$var@')' '(appsettings.G1.json 'up_np:@' 'up_np:$var@')' '(appsettings.G2.json 'up_np:@' 'up_np:$var@')' '(appsettings.G3.json 'up_np:@' 'up_np:$var@')' '(appsettings.G4.json 'up_np:@' 'up_np:$var@')' '(appsettings.PROD.json 'up_np:@' 'up_np:$var@')' '(appsettings.STG.json 'up_np:@' 'up_np:$var@')')
执行循环创建子数组:
iterate=${#arr[@]} ; for (( count=0; count<$iterate; count++ )); do eval subarr$count=${arr[$count]}; done
上述代码可成功生成subarr0、subarr1等子数组,能通过echo ${subarr1[0]} ${subarr3[2]}正常访问元素,但在同一循环内执行以下语句时报错:
echo [ "${subarr$count[1]}" - "${subarr$count[2]}" - "${subarr$count[0]}"]
错误信息:
/bin/bash: line 654: ${subarr$count[1]}: bad substitution
原因分析
Bash的参数替换语法不支持在${...}内部直接嵌套变量替换,subarr$count[1]会被当作一个完整的、非法的变量名解析,而非先替换$count再组合成数组名,因此触发语法错误。
解决方案
方案1:使用eval拼接变量名访问元素
修改循环内的echo语句,通过eval实现动态数组名的解析:
iterate=${#arr[@]} ; for (( count=0; count<$iterate; count++ )); do eval subarr$count=${arr[$count]} eval 'echo [ "${subarr'$count'[1]}" - "${subarr'$count'[2]}" - "${subarr'$count'[0]}" ]' done
或者用转义写法提高可读性:
iterate=${#arr[@]} ; for (( count=0; count<$iterate; count++ )); do eval subarr$count=${arr[$count]} eval "echo [ \"\${subarr${count}[1]}\" - \"\${subarr${count}[2]}\" - \"\${subarr${count}[0]}\" ]" done
方案2:使用Bash nameref(推荐,需Bash 4.3+)
利用Bash的nameref(名称引用)特性,无需eval即可安全处理动态数组,代码更简洁且避免eval的安全风险:
iterate=${#arr[@]} for (( count=0; count<$iterate; count++ )); do # 声明nameref,将subarr关联到subarr$count数组 declare -n subarr="subarr$count" # 赋值子数组 subarr=(${arr[$count]}) # 直接通过subarr访问元素 echo [ "${subarr[1]}" - "${subarr[2]}" - "${subarr[0]}" ] done
内容的提问来源于stack exchange,提问作者Venu Reddy
相关产品推荐
相关产品推荐

