按名称查找shell变量,间接

时间:2009-11-07 19:49:00

标签: bash eval

假设我将变量的名称存储在另一个变量中:

myvar=123
varname=myvar

现在,我想通过使用$ varname变量获得123。 有直接的方法吗?我发现没有这样的bash内置用于按名称查找,所以提出了这个:

function var { v="\$$1"; eval "echo "$v; }

所以

var $varname  # gives 123

最终看起来并不太糟糕,但我想知道我是否错过了一些更为明显的东西。提前谢谢!

5 个答案:

答案 0 :(得分:13)

来自man page of bash

${!varname}
  

如果参数的第一个字符是感叹号,则为          引入了变量间接。 Bash使用从参数的其余部分形成的变量的值作为变量的名称;          然后展开此变量,并在其余部分中使用该值          替换,而不是参数本身的值。这是          称为间接扩张。

答案 1 :(得分:12)

没有直接符合Posix的语法,只有bash主义。我经常这样做:

eval t="\$$varname"

这适用于任何Posix shell,包括那些bash是登录shell且/bin/sh更小更快的系统ash。我喜欢bash并将它用于我的登录shell,但我避免在命令文件中使用bashisms。

<小时/> 注意:编写特定于bash的脚本的一个问题是即使你可以指望安装bash,它也可能在路径上的任何地方。在这种情况下,使用完全通用的/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

当然,这不是最好的解决方案,但让我继续完成这项工作 希望我能尽快用一些更通用的东西取而代之。