Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 按名称间接查找shell变量_Bash_Eval - Fatal编程技术网

Bash 按名称间接查找shell变量

Bash 按名称间接查找shell变量,bash,eval,Bash,Eval,假设一个变量的名称存储在另一个变量中: myvar=123 varname=myvar 现在,我想通过使用$varname变量获得123。 有没有直接的方法?我没有发现用于按名称查找的bash内置项,因此得出以下结论: function var { v="\$$1"; eval "echo "$v; } 所以 最后看起来还不错,但我想知道我是否错过了更明显的东西。来自: 如果参数的第一个字符是感叹号,则为 引入了变量间接法。Bash使用由参数的其余部分

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

myvar=123
varname=myvar
现在,我想通过使用
$varname
变量获得
123
。 有没有直接的方法?我没有发现用于按名称查找的bash内置项,因此得出以下结论:

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

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

来自:

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


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

eval t="\$$varname"
这将适用于任何Posix shell,包括那些系统,
bash
是登录shell,
/bin/sh
是更小更快的东西,比如
ash
。我喜欢bash并将其用于我的登录shell,但我在命令文件中避免使用bash。

注意:编写特定于bash的脚本的一个问题是,即使您可以指望安装bash,它也可能位于路径上的任何位置。在这种情况下,使用完全通用的
/usr/bin/env
样式可能是个好主意,但请注意,这仍然不是100%可移植的,并且存在安全问题。

${!varname}
应该可以做到这一点

$ var="content"
$ myvar=var
$ echo ${!myvar}
content
我通常在需要更新Bash技能时查看

关于你的问题,请看

符号为:

Version < 2
\$$var

Version >= 2
${!varname}
版本<2
\$$var
版本>=2
${!varname}
#bmuSetIndirectVar()
#再次检查此注释和演示
#此函数是读取间接变量的助手。
#即,获取已保存名称的变量的内容
#在另一个变量中。比如:
#MYDIR=“/tmp”
#WHICHDIR=“MYDIR”
#bmuSetIndirectVar“WHICHDIR”“$MYDIR”
#
bmuSetIndirectVar(){
tmpVarName=$1
locVarName=$1
extVarName=$2

#echo“debug Ind Input>$1<>$2$tmpVarName<>$extvarname当然,就是这样。尝试使用RTFM,但不知怎的,此描述:------------${!prefix*}${!prefix@}名称匹配前缀。扩展到名称以前缀开头的变量的名称,由IFS特殊变量的第一个字符分隔。当使用@并且扩展出现在双引号内时,每个变量名称扩展到一个单独的单词。---------------在我看来并不是明显的answer、 干杯!@DigitalRoss:这个问题被标记为“bash”,那么你为什么要将答案限制为posix标准?这是一个很好的答案,它确实适用于bash。我想完美的答案应该是宣布
${!varname}
然后注意可移植性问题,以避免OP出现问题。同意,您的答案一起构成一个完美的答案:)@inger:
${!prefix*}
${!prefix@}
${!prefix}
不同,根据您需要值的上下文,您可以使用
$(eval\$$varname)
而不是作业。尝试了差不多,但错过了。比我的短-为此干杯!不是
$(..)
非posix吗?应该是
`eval\$$varname
`而不是吗?应该引用变量以避免分词
eval t=“\$$varname=”"
@JustinHoward是的,我过去常常在我的示例中不加引号,但我认为它们真的应该包括在内。修复。嗯,快速浏览指南-显然太快了:)似乎我必须正确地阅读它。谢谢你的提示!这是我选择的快速参考,我倾向于比手册页更频繁地使用它。但是你说,快速的一瞥有时是不够的。一般来说,ABS应该是用大量的盐来衡量的。不过,这个答案本身没有错。谢谢,你的答案似乎比tangens来得晚,所以我选择了那个:)在问题之前;)我不喜欢这个函数,因为我使用了“eval”这通常会触发糟糕的设计。当然,在某些地方你需要它。我喜欢的是,使用一个函数,我可以将代码从问题中分离出来,并在以后对其进行优化。甚至可能引入shell版本检查或类似的方法。这被标记为6年后提出的问题的副本?同样是IMHO这个问题+answers比链接的更清晰。顺便问一下,前面的答案在哪里@tripleee@mariotti我不明白这个问题。这个页面顶部的黄色框链接到一个重复的问题,有7个答案。我主要是根据投票数,但你会注意到,重复的同样是重复的。也许这个应该标记为相反,在确定某事物是重复的时候,问题的年龄通常不是决定因素。
$ var="content"
$ myvar=var
$ echo ${!myvar}
content
Version < 2
\$$var

Version >= 2
${!varname}
# 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}"
}