我希望echo -E n
和echo -E "n"
是等价的。然而,echo -E n
打印n
(未打印反斜杠),而echo -E "n"
打印n
(打印反斜杠)。显然,反斜杠不仅在单引号和双引号中有不同的解释,而且在双引号和引号外也有不同的解释。引号外的反斜杠是如何解释的?
反斜杠总是被删除,除非它们本身被转义(用另一个反斜杠)或在单引号或双引号内。来自POSIX标准的shell语法,第2.2.1节"转义字符(反斜杠)":
& lt; backslash>除
外,未加引号的应保留后面字符的文字值。如果a 在<反斜杠>之后,shell将其解释为行延续。& lt; backslash>和& lt; newline>应在将输入分割为令牌之前删除。自从转义的 如果从输入中完全删除并且不被任何空格替换,则它不能用作令牌分隔符。 反斜杠>
…因此,在引号之外,shell将n
解释为字面量n
。
The <必须保留其作为转义字符的特殊含义(参见转义字符(反斜杠)),只有当被认为是特殊字符时,后面跟着以下字符之一:>$ ` " <newline>
…由于在"n"
中,反斜杠是而不是后面跟着这些字符之一,因此它不保留其特殊含义,只是作为字面反斜杠传递。
顺便说一句,只是为了增加混乱,echo
的一些版本将使用另一组规则进行自己的反斜杠解释(在任何使其通过shell解析过程的情况下)。在某些版本中,-E
禁用此…但有些只是打印&;- e &;作为他们产出的一部分。如果需要可预测性,请使用printf
:
printf '%sn' n # Prints just 'n'
printf '%sn' "n" # Prints 'n'
在引号外,未转义的反斜杠总是被删除。它们仅用于禁用其他符号的特殊含义。
在双引号内,除了转义$
、`
、"
、中的一个或标记行继续符外,还保留反斜杠。
来自POSIX Shell命令语言,强调我的:
2.2.1转义字符(反斜杠)& lt; backslash>除
2.2.3双引号
用双引号括起的字符(")应保留双引号内所有字符的文字值,但反引号、<美元符号>和<反斜杠>字符除外,如下所示:反斜杠>美元符号>
[…]
The<只有当>后面跟下列字符之一时,才保留其作为转义字符的特殊含义(参见转义字符(反斜杠))当被认为是特殊的:只有当>
$
`
"