3

Is it possible to echo the two-character string -n using just the echo command built into the bash shell?

I know I can do printf '%s\n' -n but was just wondering if the echo built-in is capable of outputting the string -n at all.

Kusalananda
  • 320,670
  • 36
  • 633
  • 936
k314159
  • 393
  • 1
  • 3
  • 8
  • 6
    Covered pretty nicely in https://unix.stackexchange.com/q/65803/117549 – Jeff Schaller Apr 22 '21 at 15:59
  • I'm not sure what to think about this question. I mean, you already know the practical solution is to use `printf`, and you probably also know the background about the portability issues with `echo` in general (the things mentioned in Jeff's link). So, what's left here then? Just an exercise in doing things the hard way, or finding the exact limits of suck in a thing you know sucks? Any result you get is going to be specific some shell or shells anyway, exactly because the behaviour of `echo -n` is so hideously non-portable. – ilkkachu Apr 23 '21 at 10:19

3 Answers3

5

Using -e and octal 55 for the -:

$ echo -e '\055n'
-n

... or octal 156 for the n, or octal for both:

$ echo -e '\055\0156'
-n

If the -e is bothering you, set the shell option xpg_echo to make echo always interpret backslash sequences (this is not usually what you want though):

$ shopt -s xpg_echo
$ echo '-\0156'
-n

The echo in bash also recognizes hexadecimal:

$ echo -e '\x2d\x6e'
-n
Kusalananda
  • 320,670
  • 36
  • 633
  • 936
1

Thanks for all the answers. I'll add one of my own that I've just thought of:

echo -n -;echo n
k314159
  • 393
  • 1
  • 3
  • 8
-1

Put any character before the "-n", and use the "\b" escape sequence in -e mode to erase it in the final output. The below example uses a space for the dummy character:

$ echo -e " \b-n"
-n

Explanation:

$ man echo
       If -e is in effect, the following sequences are recognized:
       \b     backspace

This works visually for printing output to the terminal:

$ echo -e " \b-n" | tee /tmp/test
-n
$ cat /tmp/test
-n

But you may run into problems if you need to parse the output, as it does produce an invisible backspace character:

$ echo -e " \b-n" | wc -c
5
$ wc -c <<< $(echo -e " \b-n")
5
$ echo -e "--" | wc -c
3
Will Chen
  • 119
  • 3
  • But with ` \b-n` the output is not the two bytes `-n` (dash and lowercase letter n). For outputs that are similar-looking but not really the same, you could also use `echo "-n "`. The trailing white space would be less likely [citation needed] to cause issues than a surprise backspace. – ilkkachu Apr 23 '21 at 10:24