zwithouta
zwithouta

Reputation: 1581

How are backslashs interpreted outside quotation?

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

Answers (2)

Gordon Davisson
Gordon Davisson

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

Socowi
Socowi

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

Related Questions