我正在读" Bash初学者指南 ".它说:
如果第一个字符
PARAMETER
是感叹号,则Bash使用由其余部分形成的变量的值作为变量PARAMETER
的名称; 然后展开此变量,并将该值用于替换的其余部分,而不是其PARAMETER
自身的值.这被称为间接扩张.
给出的例子是:
Run Code Online (Sandbox Code Playgroud)franky ~> echo ${!N*} NNTPPORT NNTPSERVER NPX_PLUGIN_PATH
我在这里不太明白:
从其余部分形成的变量的值
PARAMETER
由于PARAMETER
是刚刚!N*
的话
其余的
PARAMETER
只是N*
.怎么会形成一个变量?Bash在那里搜索了所有可能的命令吗?
pax*_*blo 90
如果您阅读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
Run Code Online (Sandbox Code Playgroud)
F. *_*uri 20
关于这个问题迟到了,因为没有其他答案讲述nameref ...
${!var}
间接语法:~$ someVariable='Some content'
~$ var=someVariable
~$ echo $var
someVariable
~$ echo ${!var}
Some content
Run Code Online (Sandbox Code Playgroud)
declare -n
) 语法通过使用nameref,您不仅可以显示变量的内容,还可以填充变量并获取或设置属性。
~$ someVariable='Some content'
~$ declare -n var=someVariable
~$ echo $var
Some content
~$ echo ${var@A}
someVariable='Some content'
Run Code Online (Sandbox Code Playgroud)
此语法对于函数很有用:
~$ someVariable='Some content'
~$ var=someVariable
~$ echo $var
someVariable
~$ echo ${!var}
Some content
Run Code Online (Sandbox Code Playgroud)
(注:此函数只是一个示例。这不会正确扩展数组和关联数组!)
然后
~$ someVar='Hello world!'
~$ showVarDetail someVar
Variable '$someVar' is 12 len, has [] flags and contain: Hello\ world\!
~$ declare -r PI=3.14159265358979323844
~$ showVarDetail PI
Variable '$PI' is 22 len, has [r] flags and contain: 3.14159265358979323844
~$ declare -ir answerOfUltimateQestionOfLiveUniverseAndEverything=42
~$ showVarDetail answerOfUltimateQestionOfLiveUniverseAndEverything
Variable '$answerOfUltimateQestionOfLiveUniverseAndEverything' is 2 len, has [ir
] flags and contain: 42
Run Code Online (Sandbox Code Playgroud)
这可以起到双向作用!
这是一个使用两个变量名作为参数运行的小示例函数。第一个变量应包含一个字符串,第二个变量将由第一个变量内容的第一个字符填充,然后第一个变量内容将移动 1 个字符:
Run Code Online (Sandbox Code Playgroud)~$ someVariable='Some content' ~$ declare -n var=someVariable ~$ echo $var Some content ~$ echo ${var@A} someVariable='Some content'
function showVarDetail() {
local -n var=$1
printf 'Variable \47\44%s\47 is %d len, has [%s] flags and contain: %q\n' \
"$1" "${#var}" "${var@a}" "$var"
}
Run Code Online (Sandbox Code Playgroud)
然后
~$ someVar='Hello world!'
~$ shift1char someVar someChar
~$ showVarDetail someVar
Variable '$someVar' is 11 len, has [] flags and contain: ello\ world\!
~$ showVarDetail someChar
Variable '$someChar' is 1 len, has [] flags and contain: H
Run Code Online (Sandbox Code Playgroud)
经过一些小的修改:
~$ someVar='Hello world!'
~$ showVarDetail someVar
Variable '$someVar' is 12 len, has [] flags and contain: Hello\ world\!
~$ declare -r PI=3.14159265358979323844
~$ showVarDetail PI
Variable '$PI' is 22 len, has [r] flags and contain: 3.14159265358979323844
~$ declare -ir answerOfUltimateQestionOfLiveUniverseAndEverything=42
~$ showVarDetail answerOfUltimateQestionOfLiveUniverseAndEverything
Variable '$answerOfUltimateQestionOfLiveUniverseAndEverything' is 2 len, has [ir
] flags and contain: 42
Run Code Online (Sandbox Code Playgroud)
应该产生:
shift1char <variable string source> <variable target>
Run Code Online (Sandbox Code Playgroud)
Kev*_*vin 19
当给定的"间接"以a结尾时,似乎有一个例外*
,就像在这里一样.在这种情况下,它提供以您指定的部分(N
此处)开头的所有变量名称.Bash可以做到这一点,因为它跟踪变量并知道存在哪些变量.
真正的间接是这样的:
假设我有一个变量$VARIABLE
设置42
,我有另一个变量$NAME
设置为VARIABLE
. ${!NAME}
会给我的42
.您使用一个变量的值来告诉您另一个变量的名称:
$ NAME="VARIABLE"
$ VARIABLE=42
$ echo ${!NAME}
42
Run Code Online (Sandbox Code Playgroud)