为什么“echo -e”命令似乎没有产生正确的输出?

为什么“echo -e”命令似乎没有产生正确的输出?

在 Ubuntu 18.04 LTS 的终端中,当我输入此命令时:

echo -e "Hello\\\n"

它的输出如下:

Hello\n

但它应该打印,因为男人页面显示:

Hello\

也就是说,首先打印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

答案1

反斜杠被特殊处理echo -e,但首先它们是有时由 shell 特殊处理(在本例中为bash),根据 shell 的引用規則。

echo其实看到的论点是Hello\\n因为您已将 传递-eecho,所以它会对反斜杠转义进行特殊处理,并将\\其折叠为单个\。最后一个n未转义,因此它按字面意思显示。

原因是,在echoshell 自身运行之前,并且独立于其自身运行之外,\特别对待在某些情况下,但在其他情况下则不然。未加引号的\字符始终被特殊处理,单引号 \从未得到特殊对待,但双引号 \字符,就像您所运行的命令一样,更加微妙和复杂。

当 shell 在命令中遇到双引号文本时,例如,如果该文本位于双引号内本身具有特殊含义的字符之前,则"Hello\\\n"它会将其视为转义字符\而不是其他方式

  1. 因为\sometimes 在 内部具有特殊含义"",所以\紧接在另一个 之前的\具有引用第二个 的效果\。因此在双引号内,第一个\\被折叠为\
  2. 在前两个\字符之后,还有第三个\字符,它不受前两个字符的影响,并且位于 之前n。但是,n它不是在双引号内被特殊处理的字符,因此,\在这种情况下,它之前的 不会被特殊处理。因此,\n仍然是\n

效果是,在双引号中,\\\n被解释为\\n

echo -e看到时\\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,使用双引号会保留。\n\

这说明了单引号的好处:只需将您想要echo -e看到的内容放在单引号 ( echo -e 'Hello\\\n') 内即可。printf这里也很好。一个选项是printf 'Hello\\\n\n'。但printf真正出色的地方是您可以插入其他参数。您可以使用printf '%s\n\n' 'Hello\',它会插入第二个参数(字面意思,Hello\因为单引号不会改变任何东西)来代替%s

相关内容