反引号命令封装

反引号命令封装
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\``"

抑制内部膨胀。

bashPOSIX shell 和 POSIX shell(破折号)中,您可以$()作为反引号的嵌套友好替代方案。

有趣的是,内部进程替换不会扩展,$() 无论它是否被引用或内部替换是否使用反引号或$()

$ echo $(echo \$\(echo uh\))
  $(echo uh)
$ echo $(echo \`echo uh\`)
  `echo uh`

带反引号的隐式扩展看起来不太安全。我会坚持$(),特别是如果你想筑巢的话。

相关内容