我怎么能检索一个bash变量值,如果我有变量名字符串?Var1 ="this is real value" var1 =”” 通过变量a得到变量1的值。

背景:

I have some AMI's (Amazon Machine Image) and I want to fire up a few instances of each AMI. As soon as they finish booting, I want to setup each instance according to its AMI type. I don't want to bake lots of scripts or secret keys inside any AMI so I prepared a generalized startup script and I put it on S3 with a publicly accessible link. In rc.local I put small piece of code which fetches the startup script and executes it. This is all I have in the AMIs. Then each AMI accesses a common configuration script which is applicable to all AMIs and special setup scripts for each. These scripts are private and require a signed URL to access them.

所以现在,当我触发一个AMI的实例(my_private_ami_1)时,我为S3上呈现的另一个文件传递了一个签名URL,该文件包含了所有私有脚本的签名URL,以键/值对表示。config_url="http://s3.amazo.../config? "签名” my_private_ami_1 = " http://s3.amazo.../ami_1?签名” ... 当启动脚本运行时,它会下载上面的文件和源代码。然后它检查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

所以现在我可以有一个泛型代码,它可以触发实例,而不管它们的AMI类型和实例可以照顾自己。


修改了我的搜索关键词,得到了它:)。谢谢你的宝贵时间。


您可以使用${!}:

var1="this is the real value"
a="var1"
echo "${!a}" # outputs 'this is the real value'

这是一个间接参数展开的例子:

参数展开的基本形式是${parameter}。的价值 参数被替换。 如果参数的第一个字符是感叹号(!),则它 引入一个变量间接级别。的值 参数的其余部分组成的变量 变量;然后展开此变量,并将该值用于 其余的替换,而不是参数本身的值。


X=foo
Y=X
eval "Z=\$$Y"

将Z设置为foo。


现代shell已经支持数组(甚至关联数组)。所以请使用它们,少用eval。

var1="this is the real value"
array=("$var1")
# or array[0]="$var1"

然后当你想调用它时,echo ${array[0]}


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

echo ${(P)a} # outputs 'this is the real value'

它被恰当地称为参数名称替换

This forces the value of the parameter name to be interpreted as a further parameter name, whose value will be used where appropriate. Note that flags set with one of the typeset family of commands (in particular case transformations) are not applied to the value of name used in this fashion. If used with a nested parameter or command substitution, the result of that will be taken as a parameter name in the same way. For example, if you have ‘foo=bar’ and ‘bar=baz’, the strings ${(P)foo}, ${(P)${foo}}, and ${(P)$(echo bar)} will be expanded to ‘baz’. Likewise, if the reference is itself nested, the expression with the flag is treated as if it were directly replaced by the parameter name. It is an error if this nested substitution produces an array with more than one word. For example, if ‘name=assoc’ where the parameter assoc is an associative array, then ‘${${(P)name}[elt]}’ refers to the element of the associative subscripted ‘elt’.


根据答案:https://unix.stackexchange.com/a/111627

###############################################################################
# Summary: Returns the value of a variable given it's name as a string.
# Required Positional Argument: 
#   variable_name - The name of the variable to return the value of
# Returns: The value if variable exists; otherwise, empty string ("").
###############################################################################
get_value_of()
{
    variable_name=$1
    variable_value=""
    if set | grep -q "^$variable_name="; then
        eval variable_value="\$$variable_name"
    fi
    echo "$variable_value"
}

test=123
get_value_of test
# 123
test="\$(echo \"something nasty\")"
get_value_of test
# $(echo "something nasty")

数组也有同样的问题,如果你也在操作数组,下面是如何做到这一点:

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

这将输出:

ARRAY=ARRAY_NAME[@]
ARRAY=Val0 Val1 Val2
ARRAY[0]=Val0
ARRAY[1]=Val1
ARRAY[2]=Val2

在bash 4.3中,引入了对set变量的'-v'测试。同时,添加了'nameref'声明。这两个特性与间接操作符(!)一起可以实现前面示例的简化版本:

get_value()
{
  declare -n var_name=$1
  if [[ -v var_name ]]
  then
    echo "${var_name}"
  else
    echo "variable with name <${!var_name}> is not set"
  fi
}

test=123
get_value test
123

test="\$(echo \"something nasty\")"
get_value test
$(echo "something nasty")

unset test
get_value test
variable with name <test> is not set

由于这种方法消除了对“eval”的需要,因此更安全。 这段代码在bash 5.0.3(1)下检查。


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

VALUE=$(eval "echo \$$SOME_VAR_NAME")

例子

SSH_KEY_FILE_PATH_FOO="/tmp/key"
SSH_KEY_FILE_PATH_VAR_NAME_PREFIX="SSH_KEY_FILE_PATH"
SSH_KEY_FILE_PATH_VAR_NAME_SUFFIX="FOO"
SSH_KEY_FILE_PATH=$(eval "echo \$${SSH_KEY_FILE_PATH_VAR_NAME_PREFIX}_${SSH_KEY_FILE_PATH_VAR_NAME_SUFFIX}")
echo "$SSH_KEY_FILE_PATH"
/tmp/key