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


85

我正在阅读《Bash初学者指南》。它说:

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

给出的示例是:

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

我在这里不太明白:

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

由于PARAMETER是刚刚!N*的话

其余的 PARAMETER

就是N*。这如何形成变量?Bash在那里搜索了所有可能的命令吗?

Answers:


110

如果您阅读bash手册页,则基本上可以确认您所说的内容:

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

但是,从那里继续阅读:

例外情况是以下内容的扩展${!prefix*}和说明${!name[@]}

${!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

谢谢你的回答。我读过越多的《初学者入门指南》,就越会问自己作者是否理解她写的东西。
LRDPRDX

23

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

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

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

4
哇,谁知道获得生命,宇宙和一切意义的答案是如此容易!
KomodoDave 2014年

3

是的,它在!之后搜索变量的所有可能扩展。如果您已完成:

echo ${!NP*}

你只会得到NPX_PLUGIN_PATH

考虑以下示例:

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

是否将与my *匹配的其他变量也设置为“再见”?
安东尼

1
@Anthony我尝试过,如果${!my*}扩展为myA,myB,则myA将使用其当前值导出,并且myB设置为“ bye”并导出。不是很有用。
GKFX

3

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


因此,除了*情况之外,这与相同${${VAR}}吗?
chronospoon 2014年

1
@chronospoon,,简称${${VAR}}${$VAR},是不合法的,因为它$VAR返回了不能跟随$符号的字符串;要将字符串用作变量名,您需要引入一个间接级别(如原始问题本身所引用),,可以使用${!VAR},它完全符合您的期望(错误但可以理解)${$VAR}
Enrico

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.