假设我将变量的名称存储在另一个变量中:
myvar=123
varname=myvar
现在,我想通过使用$ varname变量获得123。 有直接的方法吗?我发现没有这样的bash内置用于按名称查找,所以提出了这个:
function var { v="\$$1"; eval "echo "$v; }
所以
var $varname # gives 123
最终看起来并不太糟糕,但我想知道我是否错过了一些更为明显的东西。提前谢谢!
答案 0 :(得分:13)
${!varname}
如果参数的第一个字符是感叹号,则为 引入了变量间接。 Bash使用从参数的其余部分形成的变量的值作为变量的名称; 然后展开此变量,并在其余部分中使用该值 替换,而不是参数本身的值。这是 称为间接扩张。
答案 1 :(得分:12)
没有直接符合Posix的语法,只有bash
主义。我经常这样做:
eval t="\$$varname"
这适用于任何Posix shell,包括那些bash
是登录shell且/bin/sh
更小更快的系统ash
。我喜欢bash并将它用于我的登录shell,但我避免在命令文件中使用bashisms。
/usr/bin/env
shebang 样式可能是一个好主意,但请注意,这仍然不是100%可移植的并且存在安全问题。
答案 2 :(得分:1)
${!varname}
应该做的伎俩
$ var="content"
$ myvar=var
$ echo ${!myvar}
content
答案 3 :(得分:1)
当我需要梳洗我的Bash技能时,我通常会看Advance Bash-Scripting Guide。
关于您的问题,请查看Indirect References
表示法是:
Version < 2
\$$var
Version >= 2
${!varname}
答案 4 :(得分:0)
# bmuSetIndirectVar()
# TO DOUBLE CHECK THIS COMMENT AND DEMO
# This function is an helper to read indirect variables.
# i.e. get the content of a variable whose name is saved
# within an other variable. Like:
# MYDIR="/tmp"
# WHICHDIR="MYDIR"
# bmuSetIndirectVar "WHICHDIR" "$MYDIR"
#
bmuSetIndirectVar(){
tmpVarName=$1
locVarName=$1
extVarName=$2
#echo "debug Ind Input >$1< >$2<"
eval tmpVarName=\$$extVarName
#echo "debug Ind Output >$tmpVarName< >$extVarName<"
export $locVarName="${tmpVarName}"
}
我目前正在使用这个小功能。我对它并不十分满意,我在网上看到了不同的解决方案(如果我记得我会在这里写的),但似乎有效。在这几行中,已经存在一些冗余和额外数据,但它对调试很有帮助。
如果您想查看它,即我正在使用它,请检查: https://github.com/mariotti/bmu/blob/master/bin/backmeup.shellfunctions.sh
当然,这不是最好的解决方案,但让我继续完成这项工作 希望我能尽快用一些更通用的东西取而代之。