9

I can't figure how to print the string "-n" with the over 30 years-old command echo.

I tried these:

Michaels:Scripts$ echo -n
Michaels:Scripts$ echo "-n"
Michaels:Scripts$ echo -e "-n"
Michaels:Scripts$ echo -- -n
-- -n
Michaels:Script$ echo -- "-n"
-- -n
Michaels:Script$ echo "\-n"
\-n

I use Mac OS X ML. I consider this behaviour very weird and unexpected.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
Michael
  • 299

4 Answers4

10

If you don't want to use prinf you have a couple of of options, at least according to this SO Q&A, titled: echo “-n” will not print -n?.

This seems to be your best option:

$ echo "x-n" | cut -c 2-
-n

Or some variation:

$ echo -- '-n'|cut -d" " -f2
-n

printf

printf doesn't have this issue:

$ printf "%s\n" -n
-n
slm
  • 369,824
  • Could you please explain the second command, esp. the cut-part of it :) – Michael Aug 07 '13 at 16:05
  • 1
    @Michael - sure, it takes the output from echo -- '-n', which is -- -n. cut then splits the output on spaces, and takes the 2nd field, hence the -n. – slm Aug 07 '13 at 16:06
10

Why would you want to use echo? Use printf:

printf -- '-n\n'

Or:

printf '%s\n' -n

With echo:

echo -n

Will output -n<LF> in a UNIX conformant echo.

bash, dash, GNU or zsh echo (in their default configurations on most systems) can do it with:

echo -en '-n\n'

Or (on ASCII-based systems):

echo -e '\055n'

Zsh echo can do it with:

echo - -n

Or (assuming the bsdecho option is not enabled):

echo '\u002Dn'

Fish's echo with:

echo -- -n

Ksh and Zsh's print can do it with:

print - -n

or:

print -- -n

bash (but not zsh), assuming the posix and xpg_echo are not both enabled:

echo -n -; echo n

Interestingly, it is impossible to output -n with echo alone in a POSIX way (that is, more or less, portably across Unices and Unix-likes), since the behaviour if the first argument is -n or if any argument contains backslash characters is unspecified.

  • If you have a unicode terminal, you could output \u2011 (or \u2010) which look identical to a -. But that's hardly a solution (and there's no portable way to introduce the unicode characters without knowing the encoding of the terminal emulator). – rici Aug 08 '13 at 05:48
  • I am using ksh, echo -e "\x2d" is printing "\x2d" but octal expression echo -e "\055" is printing the correct "-" . Any thoughts please? Thanks – Forever Learner May 02 '17 at 14:41
  • 1
    @CppLearner, yes echo is not portable. Don't use echo. For Unix compliant echo's echo '\055' would output the 0x2d byte (- in ASCII, but Unix systems are not required to use ASCII as their base charsets, some still use EBCDIC). But the behaviour for echo '\x2d' is unspecified. Similarly printf '\055' is POSIX and portable, printf '\x2d' is neither. – Stéphane Chazelas May 02 '17 at 14:54
  • Thank you so much Stéphane Chazelas for clarification and quick turnaround. – Forever Learner May 02 '17 at 14:55
3

For historical reasons, echo doesn't do the usual kind of argument parsing where any argument that starts with - is an option except that -- signals the end of option. The echo command mostly prints its arguments unchanged, but depending on the unix variant, on the shell and on how the shell is configured, it may interpret some options (-e, -E, -n, -) and may treat backslash+character specially.

There's no portable way to print -n with echo alone. The portable way to print a string without having to worry about special characters is

printf %s -n

or more generally print %s "$somestring". If you want to print a final newline after the string, make that printf '%s\n' -n.

0

Try this, if you need "-n" as a first two symbols:

echo -e '\r-n'

Another one way:

echo -n '-'; echo 'n'