Reputation: 1581
I'd expect echo -E \n
and echo -E "\n"
to be equivalents. However echo -E \n
prints n
(backslash is not printed) whereas echo -E "\n"
prints \n
(backslash is printed). Apparently backslashs are interpreted differently not only in single and double quotes, but also in double quotes and outside of quotes. How are backslashs interpreted outside of quotes?
Upvotes: 0
Views: 108
Reputation: 125818
Backslashes are always removed, unless they're themselves escaped (with another backslash) or inside single- or double-quotes. From the 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.
...so outside of quotes, the shell interprets \n
as a literal n
.
Inside double-quotes, on the other hand (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>
...since in "\n"
, the backslash is not followed by one of those characters, it doesn't retain its special meaning and is just passed through as a literal backslash.
BTW, just to add confusion, some versions of echo
will do their own backslash-interpretation (on any that make it past the shell's parsing process), using yet another set of rules. In some versions, -E
disables this... but some just print "-E" as part of their output. If you want predictability, use printf
instead:
printf '%s\n' \n # Prints just 'n'
printf '%s\n' "\n" # Prints '\n'
Upvotes: 3
Reputation: 27215
Outside of quotes, unescaped backslashes are always deleted. They are only used to disable the special meaning of other symbols.
Inside double quotes, backslashes are kept, except when escaping one of $
, `
, "
, \
, or marking a line continuation.
From POSIX Shell Command Language, emphasis mine:
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>
Upvotes: 2