答案1
反引号有效地为您提供了对反斜杠的双重处理。 (一次是在处理主命令行时,另一次是在命令替换中的命令时。)
就像 Kusalanda 所说,这对于$(..)
命令替换来说是不同的。
首先,我们要注意的是,我们似乎正在讨论 Bash 的echo
,默认情况下它本身不处理反斜杠转义,因此例如echo '\\'
传递\\
给echo
which prints \\
。如果您使用了echo
处理反斜杠本身的 ,(例如带有shopt -s xpg_echo
、 Dash 或 zsh 的 Bash ),您将得到最后一个\\
变成\
和\z
作为输出。
当使用旧式反引号形式的替换时,反斜杠保留其字面含义,除非后面跟着[美元符号、反引号或反斜杠]。
所以,在命令中
echo `echo \\\\\\\z` # 7 backslashes
这些\\
对首先被简化为单个\
s,并且\z
保持为\z
(它后面没有三个中的任何一个,因此反斜杠是字面意思)。然后反引号中的命令再次运行 shell。
所以命令替换中的命令最终为
echo \\\\z # 4 backslashes
其中\\
对被简化为单个\
s,并且参数echo
变为\\z
(通过两个 s 打印不变echo
,请参见上面的警告)。
您可以看到带有美元符号的类似结果,例如:
var=foo
echo `echo \$var`
印刷foo
。
echo `echo '\$x'`
印刷$x
。 (单引号不保护$
)
命令替换的形式$(...)
更明智,其内容仅被处理一次,因此:
echo $(echo \\\\\\\z) # 7 backslashes
打印\\\z
(3),以及
var=foo
echo $(echo \$var)
印刷$var
。
另请参阅:
答案2
初始 echo 命令由 shell 处理,因此它可以正确地看到倍数\
并将其减少为echo \\\z
.
此时,shell就不再涉及了。
echo 命令然后会看到\\\
,因此它会将其简化为单个\
,即您需要一个文字\
。
没有必要逃避最后\
,这样就可以减少到\\\z
。