引号外的反斜杠是如何解释的?

How are backslashs interpreted outside quotation?

我希望 echo -E \necho -E "\n" 是等价的。但是 echo -E \n 打印 n(不打印反斜杠),而 echo -E "\n" 打印 \n(打印反斜杠)。显然,反斜杠不仅在单引号和双引号中有不同的解释,而且在双引号和引号外也有不同的解释。如何解释引号外的反斜杠?

在引号之外,未转义的反斜杠总是被删除。它们仅用于禁用其他符号的特殊含义。

在双引号内,保留反斜杠,但转义 $`"\ 之一或标记续行时除外。

来自 POSIX Shell Command Language,强调我的:

2.2.1 Escape Character (Backslash)

A <backslash> that is not quoted shall preserve the literal value of the following character, with the exception of a <newline>. If a <newline> follows the <backslash>, the shell shall interpret this as line continuation. The <backslash> and <newline> shall be removed before splitting the input into tokens. [....]

2.2.3 Double-Quotes

Enclosing characters in double-quotes ( "" ) shall preserve the literal value of all characters within the double-quotes, with the exception of the characters backquote, <dollar-sign>, and <backslash>, as follows:

[...]

\
The <backslash> shall retain its special meaning as an escape character (see Escape Character (Backslash)) only when followed by one of the following characters when considered special:

$ ` " \ <newline>

反斜杠 总是 被删除,除非它们本身被转义(使用另一个反斜杠)或在单引号或双引号内。来自 POSIX standard for shell syntax, section 2.2.1 "Escape Character (Backslash)":

A <backslash> that is not quoted shall preserve the literal value of the following character, with the exception of a <newline>. If a <newline> follows the <backslash>, the shell shall interpret this as line continuation. The <backslash> and <newline> shall be removed before splitting the input into tokens. Since the escaped <newline> is removed entirely from the input and is not replaced by any white space, it cannot serve as a token separator.

...所以在引号之外,shell 将 \n 解释为文字 n

另一方面,在双引号内 (section 2.2.3 "Double-Quotes"):

\
The <backslash> shall retain its special meaning as an escape character (see Escape Character (Backslash)) only when followed by one of the following characters when considered special:
$ ` " \ <newline>

...因为在 "\n" 中,反斜杠是 而不是 后跟这些字符之一,它不保留其特殊含义,只是通过作为文字反斜杠。

顺便说一句,只是为了增加混乱,某些版本的 echo 将使用另一组进行自己的反斜杠解释(在任何通过 shell 的解析过程的情况下)的规则。在某些版本中,-E 禁用此功能...但有些版本只打印“-E”作为其输出的一部分。如果您想要可预测性,请改用 printf

printf '%s\n' \n      # Prints just 'n'
printf '%s\n' "\n"    # Prints '\n'