Pro*_*sch 18 bash zsh variable-substitution for
${!FOO}
在 中执行双重替换bash
,这意味着它采用 FOO 的(字符串)值并将其用作变量名。
zsh
不支持此功能。
有没有办法使这项工作在bash
和 中相同zsh
?
我有一个环境变量列表,比如
PATH MAIL EDITOR
Run Code Online (Sandbox Code Playgroud)
并且想先打印变量名,然后打印它们的值。
这适用于bash
但不适用于zsh
:
PATH MAIL EDITOR
Run Code Online (Sandbox Code Playgroud)
应该以某种方式可能以“旧方式”使用eval
,但我无法让它工作:
for VAR in LIST
do
echo $VAR
echo ${!VAR}
done
Run Code Online (Sandbox Code Playgroud)
我永远不会明白为什么我不能简单地进行任意深度替换,例如${${VAR}}
或即使${${${VAR}}}
需要,所以对此的解释也很好。
Fri*_*tek 25
Profpatsch 在原始问题下的评论给出了${(p)FOO}
输出间接变量引用内容的示例。标志不正确或拼写错误,它应该是大写的 P 而不是小写的 p。用途:${(P)FOO}
。
以下应产生所需的输出:
#! /bin/zsh
LIST=(PATH MAIL EDITOR)
for VAR in ${LIST}
do
print "${VAR}: ${(P)VAR}"
done
Run Code Online (Sandbox Code Playgroud)
来自zshexpn手册页;部分 -参数扩展标志:
磷
Run Code Online (Sandbox Code Playgroud)This forces the value of the parameter name to be interpreted as a further parameter name, whose value will be used where appropriate. Note that flags set with one of the typeset family of commands (in particular case trans?formations) are not applied to the value of name used in this fashion. If used with a nested parameter or command substitution, the result of that will be taken as a parameter name in the same way. For example, if you have `foo=bar' and `bar=baz', the strings ${(P)foo}, ${(P)${foo}}, and ${(P)$(echo bar)} will be expanded to `baz'
有一次我读到为什么${${${VAR}}}
没有产生您期望的输出,但此时我找不到它。您可以执行以下操作:
first="second" ; second="third" ; third="fourth" ; fourth="fifth"
print ${(P)${(P)${(P)first}}}
fifth
Run Code Online (Sandbox Code Playgroud)
Gil*_*il' 20
bash 和 zsh 都有执行间接扩展的方法,但它们使用不同的语法。
使用eval
;执行间接扩展很容易。这适用于所有 POSIX 和大多数 Bourne shell。如果值包含在 shell 中具有特殊含义的字符,请注意正确引用。
eval "value=\"\${$VAR}\""
echo "$VAR"
echo "$value"
Run Code Online (Sandbox Code Playgroud)
${${VAR}}
不起作用,因为它不是任何 shell 实现的功能。大括号内的东西必须符合不包括${VAR}
. (在 zsh 中,这是受支持的语法,但做了一些不同的事情:嵌套替换对同一值执行连续转换;${${VAR}}
等效于$VAR
因为这对值执行了两次身份转换。)