按名称间接查找 shell 变量

发布于 2024-08-10 04:39:08 字数 350 浏览 2 评论 0原文

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

myvar=123
varname=myvar

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

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

所以

var $varname  # gives 123

最后看起来还不错,但我想知道我是否错过了一些更明显的东西。

Let's say I have a variable's name stored in another variable:

myvar=123
varname=myvar

Now, I'd like to get 123 by just using $varname variable.
Is there a direct way for that? I found no such bash builtin for lookup by name, so came up with this:

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

so

var $varname  # gives 123

Which doesn't look too bad in the end, but I'm wondering if I missed something more obvious.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

御弟哥哥 2024-08-17 04:39:08

bash 手册页

${!varname}

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

From the man page of bash:

${!varname}

If the first character of parameter is an exclamation point, a level of
variable indirection is introduced. Bash uses the value of the variable formed from the rest of parameter as the name of the variable;
this variable is then expanded and that value is used in the rest of
the substitution, rather than the value of parameter itself. This is
known as indirect expansion.

油饼 2024-08-17 04:39:08

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

eval t="\$varname"

这适用于任何 Posix shell,包括那些以 bash 为登录 shell 且 /bin/sh 更小、更快的系统,例如 灰烬。我喜欢 bash 并将其用于我的登录 shell,但我避免在命令文件中使用 bashism。



Note: One problem with writing bash-specific scripts is that even if you can count on bash being installed, it could be anywhere on the path. It might be a good idea in that case to use the fully general /usr/bin/env shebang style, but note that this is still not 100% portable and has security issues.

There isn't a direct Posix-conforming syntax, only a bashism. I usually do this:

eval t="\$varname"

This will work on any Posix shell, including those systems where bash is the login shell and /bin/sh is something smaller and faster like ash. I like bash and use it for my login shell but I avoid bashisms in command files.



Note: One problem with writing bash-specific scripts is that even if you can count on bash being installed, it could be anywhere on the path. It might be a good idea in that case to use the fully general /usr/bin/env shebang style, but note that this is still not 100% portable and has security issues.

过期情话 2024-08-17 04:39:08

${!varname} 应该可以解决问题

$ var="content"
$ myvar=var
$ echo ${!myvar}
content

${!varname} should do the trick

$ var="content"
$ myvar=var
$ echo ${!myvar}
content
简单爱 2024-08-17 04:39:08

当我需要更新我的 Bash 技能时,我通常会查看高级 Bash 脚本指南

关于您的问题,请查看 间接引用

符号为:

Version < 2
\$var

Version >= 2
${!varname}

I usually look at Advance Bash-Scripting Guide when I need to freshen up my Bash skills.

Regarding your question look at Indirect References

Notation is:

Version < 2
\$var

Version >= 2
${!varname}
寒冷纷飞旳雪 2024-08-17 04:39:08
# 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

当然这不是最好的解决方案,但让我继续工作,在
希望我很快就能用更通用的东西取代它。

# 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}"
}

I am currently using this little function. I am not fully happy with it, and I have seen different solutions on the web (if I could recall I would write them here), but it seems to work. Within these few lines there is already some redundancy and extra data but it was helpful for debugging.

If you want to see it in place, i.e. where I am using it, check:
https://github.com/mariotti/bmu/blob/master/bin/backmeup.shellfunctions.sh

Of course it is not the best solution, but made me going on with the work, in
the hope I can replace it with something a bit more general soon.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文