Linux Shell间接变量引用通过${!varname}(Bash 4.3+推荐)或eval实现,用于动态获取变量值;适用于构造动态变量名、批量处理等场景,但需注意空值、非法字符、作用域及数组限制。

Linux Shell 中的间接变量引用,是指通过一个变量的值(该值本身是另一个变量的名字),去获取那个“名字变量”所存储的实际内容。它常用于动态构造变量名、处理批量数据或编写通用脚本时。
用 ${!varname} 语法最简洁安全
这是 Bash 4.3+ 原生支持的间接引用方式,推荐优先使用。前提是你要有一个变量,其值恰好是目标变量的名称。
- 先定义两个变量:
target="Hello World"<br>ref="target"
- 用
${!ref}就能取到"Hello World":echo ${!ref} # 输出:Hello World - 注意:不能写成
${!$ref}或${!{ref}},语法就是${!变量名}
用 eval 实现兼容性更强的间接引用
适用于老版本 Bash(如 3.x)或需要更复杂拼接的场景,但需谨慎使用——因为 eval 会重新解析并执行字符串,存在安全风险(尤其当变量含用户输入时)。
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 同样基于上面的变量:
target="Hello World"<br>ref="target"
- 写法:
eval "value=\$$ref"<br>echo "$value" # 输出:Hello World
- 关键点:
\$$ref先被转义为$target,再由eval执行一次展开
典型实用场景:按编号动态访问学生信息
比如有多个形如 S01_name、S02_dept 的变量,用户选了 S02,你想自动读出对应姓名和系别:
- 定义数据:
S01_name="Li Hao"; S02_name="Zhang Ju"<br>S01_dept="Computer"; S02_dept="English"
- 用户输入学号前缀:
stunum="S02" - 构造变量名并间接取值:
name_var="${stunum}_name"<br>dept_var="${stunum}_dept"<br>echo "Name: ${!name_var}" # Zhang Ju<br>echo "Dept: ${!dept_var}" # English
注意事项和常见错误
间接引用不是万能的,容易出错的地方要留心:
-
空值或未定义变量:如果
ref为空或指向不存在的变量,${!ref}返回空字符串,不会报错;eval则可能产生意外结果 -
变量名含非法字符:确保
ref的值是合法变量名(只含字母、数字、下划线,且不以数字开头) - 作用域限制:间接引用只能访问当前 shell 作用域内可见的变量(例如函数内定义的局部变量,外部无法通过间接方式读取)
-
不支持数组索引间接:不能用
${!array[@]}这类写法实现数组名间接;需配合declare -n(Bash 4.3+ 的 nameref)或改用eval










