bash 中的替换错误

Substitution error in bash

代码如下:

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

function test()
{
    data=
    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 ​​吗?

@试试:

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

function test()
{
    data=
    echo $data[Tom]

    a=$data[Tom]
    echo ${!a}
}
test data84

输出结果如下

data84[Tom]
23

解释:

来自man bash(参数扩展):

 ${parameter}

The value of parameter is substituted. The braces are required when parameter is a positional parameter with more than one
digit, or when parameter is followed by a character which is not to be interpreted as part of its name. [...]

If the first character of parameter is an exclamation point (!), a level of variable indirection is introduced. Bash uses the value of the variable formed from the rest of parameter as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of parameter itself. This is known as indirect expansion. The exceptions to this are the expansions of ${!<i>prefix</i>*} and ${!<i>name</i>[@]} described below. The exclamation point must immediately follow the left brace in order to introduce indirection.

如果您有 Bash 4.3 或更高版本,这将是使用 nameref 的绝佳机会。这样一来,您不仅可以轻松访问数组元素,还可以对它们进行赋值:

testfunc () {
    local -n data=
    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 内置函数冲突。