shell中可通过${!varname}实现变量名动态解析,即取varname值作为变量名再获取其值;支持数组元素间接访问(bash 4.3+);旧版需用eval但有安全风险;注意var必须已定义非空、不可嵌套、变量名须合法。

Shell 中可以通过间接引用(Indirect Expansion)实现变量名称的动态解析,核心是使用 ${!varname} 语法——它会把 varname 的值当作另一个变量名,再取该变量的值。
基础用法:${!varname} 实现一层间接引用
这是最常用、最安全的方式:
- 先定义目标变量:
target="Hello World" - 再定义“指向它的变量”:
ref="target" - 用
${!ref}即可取到"Hello World"
示例:
target="Hello World"
ref="target"
echo ${!ref} # 输出:Hello World支持数组和索引的间接访问
若要间接引用数组元素,需将变量名和索引拼成完整名称,再用 ${!name} 解析:
一款AI视频创作工具,主要用于蛙蛙写作辅助AI写文,帮助获取创意灵感,提供拆书、小说转剧本、视频生成等功能,是一款功能全面的AI智能写作工具,适合需要提升相关任务效率的用户。
arr=(apple banana cherry)idx=1-
varname="arr[$idx]"→ 注意:这里不能加$,必须是字面量字符串 -
echo ${!varname}→ 输出banana(Bash 4.3+ 支持)
⚠️ 注意:旧版 Bash(如 4.2 及更早)不支持带索引的间接扩展,此时需改用 eval(见下文)。
兼容性更强的替代方案:eval(慎用)
当需要更灵活的动态构造(如多层间接、含运算、旧 Shell 环境),可用 eval,但务必注意安全性:
target="final value"mid="target"outer="mid"-
eval "echo \${\${!outer}}"不合法;正确写法是:eval "echo \${$outer}"→ 先展开$outer得mid,再取$mid值 - 更清晰的写法:
eval "val=\${$outer}"; echo "$val"
⚠️ 警告:避免对不可信输入使用 eval,否则存在命令注入风险。优先用 ${!...}。
常见陷阱与注意事项
-
${!var}中的var必须是**已定义且非空**的变量名,否则结果为空(不会报错) - 不能嵌套使用,如
${!${!x}}是非法语法;需分步:y=${!x}; echo ${!y} - 变量名中不能含特殊字符或空格;间接引用只认合法标识符
- 在函数内使用时,注意作用域:被间接引用的变量需在当前作用域可见(或为全局)










