什么是间接扩张? ${!var*} 是什么意思?
我正在阅读“Bash 初学者指南”。它说:
如果
PARAMETER
的第一个字符是感叹号,Bash 使用由PARAMETER
的其余部分形成的变量值作为变量的名称;然后扩展该变量,并在其余替换中使用该值,而不是PARAMETER
本身的值。这称为间接扩展。
给出的例子是:
弗兰基~>回声 ${!N*} NNTPPORT NNTPSERVER NPX_PLUGIN_PATH
这里我不太明白:
由
PARAMETER
的其余部分形成的变量值
由于 PARAMETER
只是 !N*
,那么
其余
参数
只是 N*
。这怎么能形成一个变量呢? Bash 是否在那里搜索了所有可能的命令?
I'm reading "Bash Guide for Beginners". It says:
If the first character of
PARAMETER
is an exclamation point, Bash uses the value of the variable formed from the rest ofPARAMETER
as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value ofPARAMETER
itself. This is known as indirect expansion.
The example given is:
franky ~> echo ${!N*} NNTPPORT NNTPSERVER NPX_PLUGIN_PATH
I don't quite understand here:
the value of the variable formed from the rest of
PARAMETER
As the PARAMETER
is just !N*
, then
the rest of
PARAMETER
is just N*
. How could this form a variable? Did Bash search all possible commands there?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果您阅读了
bash
手册页,它基本上证实了您的说法:然而,从那里继续阅读:
换句话说,您的特定示例
${!N*}
是您引用的规则的例外。然而,它确实在预期的情况下发挥作用,例如:${!prefix*}
的示例:If you read the
bash
man page, it basically confirms what you have stated:However, reading on from there:
In other words, your particular example
${!N*}
is an exception to the rule you quoted. It does, however, work as advertised in the expected cases, such as:An example of
${!prefix*}
:当给定的“间接”以
*
结尾时,似乎存在异常,就像这里一样。在本例中,它给出以您指定的部分开头的所有变量名称(此处为N
)。Bash 可以做到这一点,因为它跟踪变量并知道哪些变量存在。
真正的间接是这样的:
假设我将一个变量
$VARIABLE
设置为42
,并将另一个变量$NAME
设置为VARIABLE
。${!NAME}
会给我42
。您可以使用一个变量的值来告诉您另一个变量的名称:There appears to be an exception when the given "indirection" ends in a
*
, as it does here. In this case, it gives all variable names that start with the part you specified (N
here).Bash can do that because it tracks variables and knows which ones exist.
True indirection is this:
Say I have a variable
$VARIABLE
set to42
, and I have another variable$NAME
set toVARIABLE
.${!NAME}
will give me42
. You use the value of one variable to tell you the name of another:bash 间接 和/或 nameref
在这个问题上迟到了,因为没有其他答案讲述nameref...
使用
${ !var}
间接语法:使用 namref (
declare -n
) 语法通过使用 nameref 你不仅可以显示变量的内容,还可以填充变量并获取或设置属性。
此语法对于函数很有用:(
注意:此函数只是一个示例。这不会正确扩展数组和关联数组!)
然后
使用填充变量值>nameref
这可以有两种方式!
这是一个使用两个变量名作为参数运行的小示例函数。第一个变量应包含一个字符串,第二个变量将由第一个变量内容的第一个字符填充,然后第一个变量内容将移动 1 个字符:
然后
进行一些小的修改:
应该产生:
bash indirection and/or nameref
Comming late on this question, and because no other answer tell about nameref...
Using
${!var}
indirection syntax:Using namref (
declare -n
) syntaxBy using nameref you could not only show content of variable, but you can populate variable and get or set attributes.
This syntax is usefull for functions:
(Nota: This function is only a sample. This won't expand correctly arrays and associative arrays!)
Then
Populating variable values using nameref
This could work in both ways!
Here is a little sample function to run with two variable names as arguments. First variable should contain a string and second variable will be populated by 1st character of 1st variable content, then 1st variable content will be shifted by 1 character:
Then
With some little modifications:
should produce:
是的,它会搜索 ! 之后所有可能的变量扩展。如果您已完成:
您将仅获得
NPX_PLUGIN_PATH
。考虑以下示例:
Yes, it searches for all possible expansions of variables after the !. If you had done:
you would get only
NPX_PLUGIN_PATH
.Consider the following example:
您在间接处理中遇到了异常,如果最后一个字符是
*
,则将返回具有之前给定前缀的所有变量。You've hit an exception in indirection processing, where if the last character is
*
, all variables that have the prefix given before will be returned.您可以参考这个 GNU bash 文档来获取权威信息
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html#Shell-Parameter-Expansion
但基本上是间接的作为例外之一,不会对
${!prefix*}
执行扩展,在您的示例中,N 是前缀。该文档将解释 bash 中的间接扩展是什么
You can refer to this GNU doc for bash for authoritative information
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html#Shell-Parameter-Expansion
But basically, indirect expansion is not performed on
${!prefix*}
as one of the exceptions, in your example, N is the prefix.The Document will explain what indirect expansion is in bash