我正在阅读“ Bash初学者指南”。它说:
如果
PARAMETER
的第一个字符是感叹号,则Bash使用由PARAMETER
的其余部分形成的变量的值作为变量的名称;然后展开此变量,并将该值用于替换的其余部分,而不是PARAMETER
本身的值。这被称为间接扩张。
给出的例子是:
franky ~> echo ${!N*} NNTPPORT NNTPSERVER NPX_PLUGIN_PATH
我在这里不太明白:
由
的其余部分形成的变量的值PARAMETER
由于PARAMETER
只是!N*
,所以
其余
PARAMETER
只是N*
。怎么会形成一个变量? Bash在那里搜索了所有可能的命令吗?
答案 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获取权威信息
但基本上,${!prefix*}
上不执行间接扩展作为例外之一,在您的示例中,N是前缀。
文档将解释bash中的间接扩展