yol*_*n00 21 command-line echo
在 Ubuntu 18.04 LTS 的终端中,当我写这个命令时:
echo -e "Hello\\\n"
Run Code Online (Sandbox Code Playgroud)
它给出了这个作为输出:
Hello\n
Run Code Online (Sandbox Code Playgroud)
但它应该打印,正如手册页所说:
Hello\
Run Code Online (Sandbox Code Playgroud)
也就是说,首先打印Hello,然后\是一个换行符(然后是另一个换行符)。问题出在哪儿?
请参阅以下几个echo -e命令及其输出:
man420@man420-X542UQ:~$ echo -e "HEllo\a\a\a\a\a\a\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\a\\\n"
HEllo\n
Run Code Online (Sandbox Code Playgroud)
Eli*_*gan 30
反斜杠由 特殊处理echo -e,但首先,根据 shell 的引用规则,它们有时会由 shell(在本例中为bash)进行特殊处理。
echo实际看到的论点是Hello\\n。因为你已经传递-e到echo,它特别对待反斜杠转义,并\\折叠为单个\. finaln没有被转义,所以它从字面上看。
这样做的原因是,在echo自身操作之前并与自身操作分开,shell在某些上下文中进行了特殊处理,\而在其他上下文中则不进行特殊处理。未加引号\字符总是经过特殊处理的,单引号 \都从来没有经过特殊处理,但处理的双引号 \字符,如您运行的命令,是更加微妙和复杂。
当 shell 在命令中遇到双引号文本时,就像 一样"Hello\\\n",\当它位于一个字符之前时,它会被视为转义字符,而该字符本身可以在双引号内具有特殊含义,否则。
\有时在里面有特殊含义,紧接在另一个之前的""a具有引用该第二个的效果。所以在双引号内,第一个被折叠成.\\\\\\\字符之后,还有第三个\字符,它不受前两个字符的影响并且位于n. 但n不是一个在双引号内被特殊处理过的字符,所以\在这种情况下它不会被特殊处理。如此\n停留\n。效果是,在双引号中,\\\n被解释为\\n.
当echo -esees 时\\n,第一个\从第二个中删除特殊含义,因此按字面echo打印\n该文本。
如果您的目标是打印Hello一个额外的换行符但没有反斜杠(这个问题最初是模棱两可的,而且我认为这是一个有用的例子),那么一个解决方案是删除\. 最后运行带有额外换行符的echo -e "Hello\\n"输出Hello。
更好的解决方案是使用单引号并写入echo -e 'Hello\n'. 单引号是最强的引用形式。更好的解决方案通常是使用printf而不是echo,在这种情况下就是printf 'Hello\n\n'。
如果您的目标是打印Hello\包括反斜杠,后跟一个额外的换行符,那么双引号方法是可能的,但很麻烦。要弄清楚,倒退:echo -e转换\\为\和\n到换行符,双引号转换\\为\,所以你可以用六个反斜杠 ( echo -e "Hello\\\\\\n")来做,因为\\n变成\n由于一个反斜杠转义另一个。你也可以用 5 来做,因为双引号\n在\没有被转义时会保留。
这说明了单引号的好处:只需将您想echo -e看到的任何内容放在单引号 ( echo -e 'Hello\\\n') 中。printf这里也不错。一种选择是printf 'Hello\\\n\n'。但printf真正令人眼前一亮的是,您可以插入其他参数。您可以使用printf '%s\n\n' 'Hello\', 插入第二个参数(字面意思是Hello\因为单引号不会改变任何内容)代替%s.