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

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

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

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

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

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

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

   ${!name[@]}
   ${!name[*]}
   ${!prefix*}
   ${!prefix@}

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

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


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

答案1

你的假设是正确的。

更详细的文档隐藏在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 文档站点上也。

相关内容