推荐使用 ${!varname} 实现变量间接引用,安全简洁;Bash 4.3+ 可用 declare -n 创建 nameref;应避免 eval,因其存在命令注入风险。

Linux Shell 中不能直接用一个变量的值当作另一个变量名来引用,比如 varname="user_name",然后想直接写 $varname 得到 user_name 的值 —— 这样只会输出字符串 user_name,而不是它所指向的值。要实现“变量名动态取值”,得靠 eval 或更安全的替代方案。
用 eval 实现间接引用(基础但需谨慎)
eval 会把传入的字符串当作命令重新解析执行一次,因此可以拼接出变量引用表达式再求值:
- 定义两个变量:
user_name="Alice"varname="user_name" - 用
eval获取值:eval "echo \$$varname"→ 输出Alice
或更清晰写法:eval "value=\$$varname"; echo "$value" - 原理:先拼成
value=$user_name字符串,再由eval执行,完成一次间接展开。
用 nameref(Bash 4.3+ 推荐)避免 eval
如果使用较新 Bash(4.3 及以上),declare -n 创建“名称引用”是更干净、安全的方式:
user_name="Alice"-
declare -n ref=user_name—— 声明ref是user_name的别名 - 之后直接用
echo "$ref"就等价于echo "$user_name",无需拼字符串或调用eval - 支持链式引用和修改:
ref="Bob"会真正改写user_name的值
用间接扩展 ${!varname}(最常用且安全)
Bash 内置的间接参数扩展语法 ${!varname} 是最简洁、无执行风险的方案:
- 仍以
user_name="Alice"和varname="user_name"为例 - 直接写:
echo "${!varname}"→ 输出Alice - 注意:
${!varname}只适用于单层间接;不支持嵌套如${!${!x}} - 可用于数组索引、位置参数等场景,例如:
arg1="hello"; x="arg1"; echo "${!x}"
什么情况下不该用 eval
eval 安全性低,一旦变量内容含恶意字符(如分号、命令替换、重定向),就可能触发非预期执行:
- 危险示例:
user_name='$(rm -rf /)'; varname="user_name"; eval "echo \$$varname"→ 可能执行删除命令 - 只要能用
${!varname}或nameref,就应优先避开eval -
eval仅建议用于完全可控、不含用户输入的脚本内部逻辑


















