如何解析 ${!i} (以及它的含义)?

kjo*_*kjo 1 bash shell-script bash-expansion

${!i}我在 for 循环体中遇到了以下形式

for ((i=$#; i>0; i--)); do
    # ...
    if <SOME_TEST>; then
        # ...
        accumulator="${!i}:${accumulator}"
        # ...
    fi
    # ...
done
Run Code Online (Sandbox Code Playgroud)

考虑到这个可能值的范围,我的猜测是这${!i}意味着“扩展为i第一个位置参数”。

不管怎样,我想更多地了解这个符号。(特别是, 是 的${!i}特殊情况$@,还是适用于任何数组的语法的特定实例?这就是为什么我对如何解析表达式感到好奇。)

不过,我找不到这个符号的文档。如果我在bash手册页中搜索序列${!,我只找到以下字符串

   ${!name[@]}
   ${!name[*]}
   ${!prefix*}
   ${!prefix@}
Run Code Online (Sandbox Code Playgroud)

...而且我无法将围绕这些事件的文档与我正在困惑的代码相匹配。

(实际上,如果可能的话,请在您的答案中引用任何相关文档,以便我可以找出我错过的原因。)


for编辑:对于我原来的帖子,我从原始代码中复制了错误的行。我现在已经修好了。(不过,解释是一样的。)

Kus*_*nda 5

你的假设是正确的。

更详细的文档隐藏在info bash

3.5.3 Shell参数扩展

[...]

参数展开的基本形式是${PARAMETER}。的值 PARAMETER被替换。这PARAMETER是如上所述的 shell 参数 (*note ShellParameters::) 或数组引用 (*note Arrays::)。当 是具有PARAMETER多于一位数字的位置参数,或者PARAMETER后跟不被解释为其名称一部分的字符时,需要使用大括号。

如果 的第一个字符PARAMETER是感叹号 ( !),并且 PARAMETER不是 NAMEREF,则它会引入一级变量间接寻址。Bash 使用由其余部分形成的变量值PARAMETER作为变量的名称;然后扩展该变量,并在其余替换中使用该值,而不是其PARAMETER本身的值。这称为“间接扩展”。如果 PARAMETER是 nameref,则扩展为引用的变量的名称,而PARAMETER不是执行完整的间接扩展。例外情况是下面描述的${!PREFIX*}扩展 ${!NAME[@]}。感叹号必须紧跟在左大括号之后才能引入间接关系。

为方便起见,您也可以在 GNU.org 文档站点上找到这部分文档。