Backslashes are treated specially by
echo -e, but first they are sometimes treated specially by the shell (which in this case is
bash), according to the shell's quoting rules.
echo actually sees is
Hello\\n. Because you have passed
echo, it treats backslash escapes specially, and
\\ is collapsed to a single
\. The final
n is not escaped, so it appears literally.
The reason for this is that, prior to and separately from the operation of
echo itself, the shell treats
\ specially in some contexts but not others. Unquoted
\ characters are always treated specially, single-quoted
\ are never treated specially, but the treatment of double-quoted
\ characters, as in the command you ran, is more subtle and complicated.
When the shell encounters double-quoted text in a command, as with
"Hello\\\n", it treats
\ as an escape character when it precedes a character that can itself have special meaning inside double quotes and not otherwise.
\ sometimes has a special meaning inside
\ that immediately precedes another
\ has the effect of quoting that second
\. So inside double quotes, the first
\\ are collapsed into
- After those first two
\ characters, there is a third
\ character which is unaffected by those first two and which precedes an
n is not a character that is ever treated specially inside double quotes, so the
\ before it is not treated specially in this situation. Thus
The effect is that, in double quotes,
\\\n is interpreted as
echo -e sees
\\n, the first
\ removes special meaning from the second, so
\n literally for that text.
If your goal is to print
Hello with an extra newline but no backslashes (the question was originally ambiguous about this, plus I think it is a useful example), then one solution is to remove a
echo -e "Hello\\n" outputs
Hello with an extra newline at the end.
A better solution is to use single quotes and write
echo -e 'Hello\n'. Single quotes are the strongest form of quoting. An even better solution is usually to use
printf instead of
echo, which in this case would be
If your goal is to print
Hello\ including the backslash, followed by an extra newline, then the double-quoted approach is possible but cumbersome. To figure it out, work backwards:
echo -e converts
\n to a newline, and double-quoting converts
\, so you can do it with six backslashes (
echo -e "Hello\\\\\\n"), because
\\n turns into
\n due to one backslash escaping another. You can also do it with five, because double-quoting retains
\n when the
\ is not escaped.
This illustrates the benefit of single quoting: just put whatever you want
echo -e to see inside the single quotes (
echo -e 'Hello\\\n').
printf is also good here. One option is
printf 'Hello\\\n\n'. But where
printf really shines is that you can plug in additional arguments. You can use
printf '%s\n\n' 'Hello\', which inserts the second argument (literally
Hello\ because single quotes don't change anything) in place of