从函数的输出创建 Bash 关联数组:为什么“declare -A foo=$(bar)”有效,但“declare -A foo; foo=$(bar)”无效?

jra*_*ali 4 bash shell

考虑以下 bash 片段。在其中,我以不同的方式创建两个关联数组,然后打印其中一个条目。

场景 1.在一个语句中声明和赋值。按预期工作:

make_person() { echo '([firstName]=Bob [lastName]=Black)'; }
declare -A person1=$(make_person)
echo "${person1[firstName]}"
Run Code Online (Sandbox Code Playgroud)

输出:

Bob
Run Code Online (Sandbox Code Playgroud)

场景 2.在两条不同的行上声明和分配。无输出:

declare -A person2
person2=$(make_person)
echo "${person2[firstName]}"
Run Code Online (Sandbox Code Playgroud)

输出:

为什么方案 1 可以成功打印[firstName]条目而方案 2没有?两个场景都定义了和预期的行为吗?

Kam*_*Cuk 7

因为declare 重新解释和解析参数以检测( )变量赋值,然后进行数组赋值。而在正常分配var=anything始终是一个正常的分配,在var=(anything)所述( )检测到解析时的表达(当bash读取的行/输入来执行)。declare更像是eval,它重新评估输入。

场景 1 成功打印 [firstName] 条目而场景 2 没有打印的 bash 特定原因是什么?

“bash 特定原因”是我猜它是这样编程的。原因也是为了与 POSIX 兼容,因此var=$(anything)应该会像 POSIX 一样产生一个正常的变量。

是否定义了两种场景

“定义”有点太多了,我在 bash 文档中没有看到关于这个特定语法的太多内容,但是

和预期的行为?

是的,这是按预期工作的。

  • 确切地。shell 扩展 `$(make_person)` ,结果 `declare` 在场景 1 中收到合法的复合赋值。在场景 2 中,该赋值被视为标量,因为等号后面没有跟左括号,并且扩展为之后执行。 (2认同)