代码之家  ›  专栏  ›  技术社区  ›  bhups

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

  •  98
  • bhups  · 技术社区  · 16 年前

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

    var1="this is the real value"
    a="var1"
    Do something to get value of var1 just using variable a.
    

    我有一些阿美族的( Amazon Machine Image )我想激发每个AMI的几个实例。一旦他们完成引导,我想根据每个实例的AMI类型设置它们。我不想在任何AMI中烘焙大量脚本或密钥,所以我准备了一个通用的启动脚本,并将其放在上面 S3

    现在,当我启动一个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"
    ...
    
    当启动脚本运行时,它下载上述文件并 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
    

    5 回复  |  直到 6 年前
        1
  •  306
  •   Phil Ross Matt Johnson-Pint    7 年前

    ${!a} :

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

    这是一个间接的例子 parameter expansion :

    ${parameter} . 价值 parameter

    如果 参数 是感叹号(!),信息技术 引入了一个级别的变量间接寻址。Bash使用 由其他变量组成的变量 作为 替代的其余部分,而不是 它本身

        2
  •  31
  •   try-catch-finally zloctb    9 年前
    X=foo
    Y=X
    eval "Z=\$$Y"
    

    将Z设置为“foo”

    当心 使用 eval ${Y} . 这可能会通过代码注入造成伤害。

    Y="\`touch /tmp/eval-is-evil\`"
    

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

        3
  •  14
  •   smac89    5 年前

    对于我的zsh用户同伴来说,实现与公认答案相同的功能的方法是:

    ${(P)a}

    它被恰当地称为 Parameter name replacement

    这将强制将参数名称的值解释为 请注意,使用命令的typeset系列之一设置的标志(在 特殊情况转换)不应用于名称的值 以这种方式使用。

    这将以相同的方式作为参数名。例如 如果有foo=bar和bar=baz,字符串${(P)foo}, ${(P)${foo}}和${(P)$(echo bar)}将扩展到baz。

    同样,如果引用本身是嵌套的,则 如果此嵌套替换生成的数组包含更多元素,则为错误 是关联数组,则${${(P)name}[elt]}引用

        4
  •  10
  •   bhups    16 年前

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

    eval a=\$$a
        5
  •  2
  •   Alexandre Hamon    6 年前

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

    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
    
        6
  •  1
  •   user8150417    5 年前

    在bash4.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
    

    由于这种方法不需要“评估”,因此更安全。 这段代码在bash5.0.3(1)下进行了检查。

        7
  •  0
  •   ghostdog74    16 年前

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

        8
  •  0
  •   VFein    7 年前

    根据答案: 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")