Bash for循环用变量拼接数组名报bad substitution如何解决
问题原因
Bash 原生语法不支持嵌套的参数展开,你编写的${lst_${i}[@]}属于两层嵌套替换逻辑,Bash 解析参数时不会递归处理展开结果里的${}结构,因此直接报bad substitution(坏替换)错误。
解决方案
根据使用的Bash版本,选下面任意一种写法即可实现需求:
方案1:使用nameref名称引用(推荐,Bash 4.0及以上版本支持,写法安全简洁)
declare -n可以声明一个指向其他变量的引用,操作引用变量等价于直接操作原变量,完美适配数组遍历场景:lst_1=(A B C) lst_2=(D E F) for i in 1 2; do # 声明arr为指向lst_$i的名称引用 declare -n arr="lst_$i" for j in "${arr[@]}"; do echo "$j" done done执行后会按顺序输出A、B、C、D、E、F,和直接遍历单个数组的效果完全一致。注意nameref的变量名不要和目标数组名重名,避免触发循环引用问题。
方案2:使用eval构造展开表达式(兼容Bash 3.x等老版本)
如果是CentOS 6等自带老版本Bash的环境,可以用eval先拼接出完整的数组访问语句再执行,注意做好转义避免特殊字符解析异常:lst_1=(A B C) lst_2=(D E F) for i in 1 2; do # 先构造数组展开语句,将对应数组的所有元素存入临时数组elements eval "elements=(\"\${lst_$i[@]}\")" for j in "${elements[@]}"; do echo "$j" done done该写法和nameref效果一致,但因为eval会直接执行拼接后的语句,如果数组内容包含不可信的特殊字符串,可能存在命令注入风险,优先推荐用nameref方案。
内容的提问来源于stack exchange,提问作者mike
相关产品推荐
相关产品推荐

