引号外的反斜杠是如何解释的?
How are backslashs interpreted outside quotation?
我希望 echo -E \n
和 echo -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'
我希望 echo -E \n
和 echo -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'