什么是间接扩张? $ {!var *}是什么意思?

时间:2011-12-15 05:11:36

标签: bash indirection

我正在阅读“ Bash初学者指南”。它说:

  

如果PARAMETER的第一个字符是感叹号,则Bash使用由PARAMETER的其余部分形成的变量的值作为变量的名称;然后展开此变量,并将该值用于替换的其余部分,而不是PARAMETER本身的值。这被称为间接扩张。

给出的例子是:

franky ~> echo ${!N*}
NNTPPORT NNTPSERVER NPX_PLUGIN_PATH

我在这里不太明白:

  

PARAMETER

的其余部分形成的变量的值

由于PARAMETER只是!N*,所以

  

其余PARAMETER

只是N*。怎么会形成一个变量? Bash在那里搜索了所有可能的命令吗?

5 个答案:

答案 0 :(得分:84)

如果您阅读bash手册页,它基本上确认了您所声明的内容:

  

如果参数的第一个字符是感叹号(!),则引入一个变量间接的级别。 Bash使用从参数的其余部分形成的变量的值作为变量的名称;然后展开此变量,并将该值用于替换的其余部分,而不是参数本身的值。这被称为间接扩张。

然而,从那里继续阅读:

  

例外情况是下文所述的${!prefix*}${!name[@]}的扩展。

     

${!prefix*} 为匹配前缀命名。扩展为名称以prefix开头的变量名称,以IFS特殊变量的第一个字符分隔。

换句话说,您的特定示例${!N*}是您引用的规则的例外。然而,它 的工作方式与预期的情况相同,例如:

$ export xyzzy=plugh ; export plugh=cave

$ echo ${xyzzy}  # normal, xyzzy to plugh
plugh

$ echo ${!xyzzy} # indirection, xyzzy to plugh to cave
cave

答案 1 :(得分:19)

当给定的“间接”在*中结束时,似乎有一个例外,就像在这里一样。在这种情况下,它提供以您指定的部分开头的所有变量名称(此处为N)。 Bash可以做到这一点,因为它跟踪变量并知道存在哪些变量。

真正的间接是这样的:
假设我将变量$VARIABLE设置为42,并且我将另一个变量$NAME设置为VARIABLE${!NAME}会给我42。您使用一个变量的值来告诉您另一个变量的名称:

$ NAME="VARIABLE"
$ VARIABLE=42
$ echo ${!NAME}
42

答案 2 :(得分:3)

是的,它会在!之后搜索所有可能的变量扩展。如果你做了:

echo ${!NP*}

你只会获得NPX_PLUGIN_PATH

考虑以下示例:

:~> export myVar="hi"
:~> echo ${!my*}
    myVar
:~> export ${!my*}="bye"
:~> echo $myVar
    bye

答案 3 :(得分:2)

您在间接处理中遇到异常,如果最后一个字符为*,则将返回前面给出前缀的所有变量。

答案 4 :(得分:0)

您可以参考此GNU文档中的bash获取权威信息

https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html#Shell-Parameter-Expansion

但基本上,${!prefix*}上不执行间接扩展作为例外之一,在您的示例中,N是前缀。

文档将解释bash中的间接扩展