【问题标题】:Substitution error in bashbash中的替换错误
【发布时间】:2017-02-26 01:22:36
【问题描述】:

代码如下:

declare -A data84
data84=( [Tom]=23 [Lucy]=32 )

function test()
{
    data=$1
    echo ${${data}[Tom]} #error 1: "${${data}[Tom]}" bad substitution

    a=${data}[Tom]
    echo ${a} #output unwanted result data84[Tom]
}
test data84

我希望这个函数能够在调用echo ${data84[Tom]} 时提供23。你能解释一下为什么我得到错误 1 ​​吗?

【问题讨论】:

    标签: bash associative-array substitution


    【解决方案1】:

    如果您有 Bash 4.3 或更高版本,这将是使用 nameref 的绝佳机会。这样做,您不仅可以访问数组元素而不会扭曲,还可以分配给它们:

    testfunc () {
        local -n data=$1
        echo "In testfunc: ${data[Tom]}"
        data[Lucy]=99
    }
    
    declare -A data84
    data84=([Tom]=23 [Lucy]=32)
    
    testfunc data84
    
    echo "After testfunc:"
    declare -p data84
    

    这将打印出来

    In testfunc: 23
    After testfunc:
    declare -A data84='([Tom]="23" [Lucy]="99" )'
    

    所以我们实际上改变了data84

    注意test 是一个危险的函数名称,因为它可能与test shell 内置函数发生冲突。

    【讨论】:

    • 你能解释一下“local -n”在这里的作用吗?我没有找到它的解释。谢谢。
    • @user6948979 在手册中:Shell parameters(最后三段)和The declare builtin(在-n 下)。它创建对另一个变量的引用。另请参阅 Bash Hackers WikiBashFAQ/006BashFAQ/048
    • echo "In testfunc: ${data[Tom]}" 为什么不echo "In testfunc: ${${data}[Tom]}"?当我做echo ${data} 时,它什么也没给我。你能对此发表评论吗?
    • @user6948979 这就是访问关联数组中元素的方式。 ${data},对于一个数组,默认为${data[0]},因为它是空的,所以你得到的是空字符串。一旦您将data 设为data84 的名称引用,它的行为就像 data84
    【解决方案2】:

    @try:

    declare -A data84
    data84[Tom]=23
    data84[Lucy]=32
    
    function test()
    {
        data=$1
        echo $data[Tom]
    
        a=$data[Tom]
        echo ${!a}
    }
    test data84
    

    输出如下

    data84[Tom]
    23
    

    说明:

    来自 man bash(参数扩展):

     ${parameter}
    

    parameter 的值被替换。大括号是必需的 当 parameter 是具有多个位置的参数时
    数字,或者当 parameter 后跟一个不是 被解释为其名称的一部分。 [...]

    如果parameter的第一个字符是感叹号(!), 引入了变量间接级别。 Bash 使用的值 由 parameter 的其余部分组成的变量作为 多变的;然后扩展此变量,并将该值用于 其余的替换,而不是 parameter 的值 本身。这称为间接扩展。例外情况 是${!<i>prefix</i>*} 的扩展和 ${!<i>name</i>[@]} 如下所述。感叹号 必须紧跟左大括号才能引入 间接。

    【讨论】:

      猜你喜欢
      • 2014-01-04
      • 1970-01-01
      • 2012-02-19
      • 2015-07-03
      • 1970-01-01
      • 2014-09-07
      相关资源
      最近更新 更多