如果变量名存储为字符串,如何获取变量值?

bhu*_*ups 122 string bash

如果我将变量名称作为字符串,如何检索bash变量值?

var1="this is the real value"
a="var1"
Do something to get value of var1 just using variable a.
Run Code Online (Sandbox Code Playgroud)

语境:

我有一些AMI(亚马逊机器映像),我想启动每个AMI的几个实例.一旦完成启动,我想根据其AMI类型设置每个实例.我不想在任何AMI中烘焙大量脚本或密钥,因此我准备了一个通用的启动脚本,并将其放在S3上,并提供可公开访问的链接.在rc.local中,我放了一小段代码来获取启动脚本并执行它.这就是我在AMI中所拥有的一切.然后,每个AMI访问一个通用配置脚本,该脚本适用于所有AMI和每个AMI的特殊设置脚本.这些脚本是私有的,需要签名URL才能访问它们.

所以现在,当我触发AMI的一个实例(my_private_ami_1)时,我会在S3上显示另一个文件的签名URL,该文件包含所有私有脚本在键/值对方面的签名URL.

config_url="http://s3.amazo.../config?signature"
my_private_ami_1="http://s3.amazo.../ami_1?signature"
...
Run Code Online (Sandbox Code Playgroud) 当启动脚本运行时,它会下载上面的文件并且source是它.然后它检查其AMI类型并为自己选择正确的设置脚本.

ami\_type=GET AMI TYPE #ex: sets ami\_type to my\_private\_ami\_1
setup\_url=GET THE SETUP FILE URL BASED ON AMI\_TYPE # this is where this problem arises
Run Code Online (Sandbox Code Playgroud)

所以现在我可以拥有一个通用代码,它可以触发实例而不管它们的AMI类型和实例可以自己处理.

Phi*_*oss 221

你可以用${!a}.

这是间接参数扩展的示例:

参数扩展的基本形式是${parameter}.值 parameter被替换.

如果第一个字符parameter是感叹号(!),则它引入了一个变量间接的级别.Bash使用从其余部分形成的变量的值作为变量parameter的名称; 然后展开此变量,并将该值用于替换的其余部分,而不是其parameter自身的值.

  • @ 23inhouse你使用`/ bin/sh`运行脚本吗?如果是这样,请尝试使用`/ bin/bash`.从Debian Squeeze开始,`/ bin/sh`被更改为[dash`而不是`bash`]的符号链接(https://wiki.debian.org/Shell#Default_.2Fbin.2Fsh_shell).`dash`不支持这种特殊的语法,并会输出一个'Bad substitution`错误. (11认同)
  • 有没有办法让这个适用于属于数组的变量名? (8认同)
  • 这在OSX bash中对我有效,但对debian不适用?在debian上,我收到“错误替换”错误。 (3认同)

小智 25

X=foo
Y=X
eval "Z=\$$Y"
Run Code Online (Sandbox Code Playgroud)

将Z设为"foo"

小心使用,eval因为这可能允许通过值的意外执行代码${Y}.这可能会通过代码注入造成伤害.

例如

Y="\`touch /tmp/eval-is-evil\`"
Run Code Online (Sandbox Code Playgroud)

会创造/tmp/eval-is-evil.rm -rf /当然,这也可能是一些.


小智 15

在 bash 4.3+ 中,您可以使用declare -n

#!/usr/bin/env bash

var="this is the real value"
var_name="var"

declare -n var_ref=$var_name
echo "${var_ref}"
Run Code Online (Sandbox Code Playgroud)


Ale*_*mon 9

数组也有同样的问题,如果您也操作数组,请按以下步骤操作:

array_name="ARRAY_NAME"
ARRAY_NAME=("Val0" "Val1" "Val2")

ARRAY=$array_name[@]
echo "ARRAY=${ARRAY}"
ARRAY=("${!ARRAY}")
echo "ARRAY=${ARRAY[@]}"
echo "ARRAY[0]=${ARRAY[0]}"
echo "ARRAY[1]=${ARRAY[1]}"
echo "ARRAY[2]=${ARRAY[2]}"
Run Code Online (Sandbox Code Playgroud)

这将输出:

ARRAY=ARRAY_NAME[@]
ARRAY=Val0 Val1 Val2
ARRAY[0]=Val0
ARRAY[1]=Val1
ARRAY[2]=Val2
Run Code Online (Sandbox Code Playgroud)


bhu*_*ups 8

修改了我的搜索关键字并得到它:).

eval a=\$$a
Run Code Online (Sandbox Code Playgroud) 谢谢你的时间.


sma*_*c89 6

对于我的zsh同仁用户,完成与接受的答案相同的事情的方法是使用:

${(P)a}

称为参数名称替换

这将强制将参数名称的值解释为另一个参数名称,将在适当的地方使用其值。请注意,使用排版类型的命令系列之一设置的标志(在特殊情况下是转换)不会应用于以这种方式使用的名称值。

如果与嵌套参数或命令替换一起使用,则其结果将以相同的方式用作参数名称。例如,如果您具有'foo = bar'和'bar = baz',则字符串$ {(P)foo},$ {(P)$ {foo}}和$ {(P)$(echo bar) }将扩展为'baz'。

同样,如果引用本身是嵌套的,则将带有标志的表达式视为直接用参数名称替换。如果此嵌套替换产生一个包含多个单词的数组,则会出现错误。例如,如果参数assoc是关联数组的'name = assoc',则'$ {$ {(P)name} [elt]}'指的是关联下标'elt'的元素。