关于Bash间接参数展开二次扩展机制的疑问与求解
Bash间接参数扩展的二次扩展机制疑问
Bash手册3.5.3 Shell参数扩展章节明确说明:间接参数展开后的结果值会进行波浪线扩展、参数扩展、命令替换和算术扩展。但实际测试后发现大部分场景并未触发该二次扩展,特此请教其工作机制。
无效测试案例
# 尝试将命令替换结果作为间接引用的变量名 a='$(echo b)'; echo "${!a}" # 报错:bash: $(echo b): invalid variable name # 间接引用的变量值包含命令替换,但未被扩展 a='b'; b='$(echo c)'; echo "${!a}" # 输出:$(echo c) # 嵌套间接展开的语法错误 a="b"; b="c"; echo "${!$a}" # 报错:bash: ${!$a}: bad substitution # 双重感叹号的语法错误 a="b"; b="c"; echo "${!!a}" # 报错:bash: ${!!a}: bad substitution # 变量名包含$符号,无法识别 a='$b'; b='c'; echo "${!a}" # 报错:bash: $b: invalid variable name # 变量名包含!符号,无法识别 a='!b'; b='c'; echo "${!a}" # 报错:bash: !b: invalid variable name
唯一生效的场景:数组索引
观测到数组索引场景下,间接参数展开后的内容会触发二次扩展:
x='a[$(ls>&2)]' echo "${!x}"
执行时会先运行ls命令,再尝试访问数组a对应索引的元素。
核心疑问
- 这种二次扩展的生效逻辑是什么?是否真如手册所述仅针对间接参数展开的“值”?
- 二次扩展是仅严格限制于数组索引场景,还是对所有参数扩展都适用?
- 我的理解存在哪些误区?目前除数组索引外,找不到其他触发二次扩展的案例。
补充说明
既然a='b[@]'; echo "${!a}"可以正确展开为数组b的所有元素,我原本认为a='!b'; echo "${!a}"也应该实现嵌套间接引用,但实际报错。必须通过a="${!b}"; echo "${!a}"的两步操作才能达到预期效果。
内容的提问来源于stack exchange,提问作者MacBeth
相关产品推荐
相关产品推荐

