test@debian:~$ echo `echo \`echo "uh!"\``
uh!
Bash 是如何做到这一点的?看起来它首先执行非转义反引号中的表达式,它返回(双引号“”被删除,对吧?):
`echo uh!`
所以我们有一个相当于的输入:
test@debian:~$ echo `echo uh!`
(旁注:真的,为什么它有效?因为:
test@debian:~$ echo `echo uh!`
-bash: !`: event not found
)
然后 Bash 再次执行反引号中的表达式,得到:
test@debian:~$ echo uh!
最终给我们输出:
uh!
是对的吗?以及如何封装四 echo
-反引号表达式互相转换?
答案1
取决于您的版本bash
:
bash-4.2$ echo `echo \`echo "uh!"\``
bash: !"\``: event not found
bash-4.3$ echo `echo \`echo "uh!"\``
uh!
在 中bash-4.3
,!"
不再有资格作为历史事件指示符,因此历史扩展不适用。
除此之外,它只是普通的反引号嵌套语法。在反引号内,反斜杠字符被重载(再次)以再次进行嵌套扩展。
您可以根据需要嵌套任意多个级别:
echo `echo \`echo \\\`echo \\\\\\\`echo whatever\\\\\\\`\\\`\``
这相当于:
echo $(echo $(echo $(echo $(echo whatever))))
但请注意,在这两个版本中,命令替换都会受到分词的影响。因此,您需要引用它们来防止这种情况发生。
使用bash
, dash
, pdksh
, yash
, zsh
,相对容易:
echo "`echo "\`echo "\\\`echo "\\\\\\\`echo whatever\\\\\\\`"\\\`"\`"`"
使用 Bourne 或 Korn shell,您还需要转义"
while,这样就变成:
echo "`echo \"\`echo \\\"\\\`echo \\\\\\\"\\\\\\\`echo whatever\\\\\\\`\\\\\\\"\\\`\\\"\`\"`"
与之比较:
echo "$(echo "$(echo "$(echo "$(echo whatever)")")")"
答案2
这很有趣。
这扩展到呃:
echo `echo \`echo uh\``
甚至没有
echo "`echo \`echo uh\``"
抑制内部膨胀。
在bash
POSIX shell 和 POSIX shell(破折号)中,您可以$()
作为反引号的嵌套友好替代方案。
有趣的是,内部进程替换不会扩展,$()
无论它是否被引用或内部替换是否使用反引号或$()
:
$ echo $(echo \$\(echo uh\))
$(echo uh)
$ echo $(echo \`echo uh\`)
`echo uh`
带反引号的隐式扩展看起来不太安全。我会坚持$()
,特别是如果你想筑巢的话。