如何编写Bash函数以同时输出变量名与对应值,简化调试时的重复代码
这个需求我太懂了——每次调试都要手动写echo "变量名: $变量名"这种重复语句,确实麻烦又容易出错!咱们先把你之前尝试失败的核心问题说清楚,再给你几个直接能用的解决方案。
首先,你之前的函数没跑通的关键原因是参数传递的类型错了:当你调用print "$var"时,你传给函数的是变量var的值(也就是那个Google URL),而非变量名var本身。函数里拿到的是一串URL字符串,自然没法反向找到对应的变量名——毕竟Bash里没法从值反推变量名(说不定有多个变量存了同一个值呢)。
可行方案:传递变量名+间接引用
正确的思路是直接把变量名传给函数,再用Bash的「间接引用」语法获取变量的值。看这个最简实现:
# 定义print函数,接收变量名作为参数 print() { # $1是传入的变量名,${!1}是间接引用,获取该变量名对应的值 echo "$1: ${!1}" } # 测试用例 var=https://www.google.com # 注意:这里传的是变量名var,不是$var! print var
运行后会输出:
var: https://www.google.com
完全满足你想要的「避免重复写变量名」的需求!
扩展:支持同时输出多个变量
如果需要一次调试多个变量,还可以把函数改成支持多参数的版本:
print() { # 遍历所有传入的变量名参数 for var_name in "$@"; do echo "$var_name: ${!var_name}" done } # 测试多个变量 var1=hello var2=world var3=bash_debug # 一次传递多个变量名 print var1 var2 var3
输出结果:
var1: hello var2: world var3: bash_debug
为什么你的尝试失败了?
再回头看你写的非工作函数:
function print { t=$1; echo "$(echo ${!t@} | awk '{print $1}'): $t"; } var=https://www.google.com print "$var"
当你调用print "$var"时,函数里的$1是变量var的值(那个URL),不是变量名var。${!t@}是在查找「以t的值(URL)为前缀的变量名」,显然不存在这样的变量,所以输出自然不对。
其他避免重复的思路?
其实在Bash的调试场景里,「传递变量名+间接引用」已经是最简洁可靠的方案了。你之前参考的${!t@}语法是用来批量匹配变量名的,在这个单变量调试的场景下反而绕了弯路。
如果实在纠结不想写变量名(比如觉得print var不如print "$var"顺手),那其实没有完美解——因为值到变量名的映射不是唯一的,系统没法确定你指的是哪个变量,所以传递变量名的方式才是最稳妥的。
备注:内容来源于stack exchange,提问作者Signor Pizza

