21

In the terminal of Ubuntu 18.04 LTS, when I write this command:

echo -e "Hello\\\n"

It gives this as the output:

Hello\n

But it should print, as the man page says:

Hello\

That is, first print Hello, then \, then a newline character (and then another newline). Where is the problem?

See these few echo -e commands and their output:

man420@man420-X542UQ:~$ echo -e "HEllo\a\a\a\a\a\a\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\a\\\n"
HEllo\n
  • yes.for first 2 \ it should output a \.and last \ and n make a backslash escape \n(new line).so why it should print Hello\ – yolin00 Aug 31 '19 at 17:50
  • 1
    Try it without the quotes. – ajgringo619 Aug 31 '19 at 18:08
  • 2
    An amazing answer was provided by Eliah Kagan, which you should accept. – vanadium Sep 1 '19 at 7:58
  • 2
    Don't use echo in the first place: use printf. – chepner Sep 1 '19 at 19:52
  • 2
    Always use single quotes if you want to be sure that what you write is precisely what is passed to the command as argument. – Giacomo Alzetta Sep 2 '19 at 9:01
29

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.

The argument echo actually sees is Hello\\n. Because you have passed -e to 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.

  1. Because \ sometimes has a special meaning inside "", a \ that immediately precedes another \ has the effect of quoting that second \. So inside double quotes, the first \\ are collapsed into \.
  2. After those first two \ characters, there is a third \ character which is unaffected by those first two and which precedes an n. But 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 \n stays \n.

The effect is that, in double quotes, \\\n is interpreted as \\n.

When echo -e sees \\n, the first \ removes special meaning from the second, so echo prints \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 \. Running 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 printf 'Hello\n\n'.

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 \\ to \ and \n to a newline, and double-quoting converts \\ to \, 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 %s.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.