I know that echo -e
is not an ordinary command. I have tried echo '-e'
and echo \-e
but they still don`t work.

- 829,060
5 Answers
The best solution is not to use echo
, but to use printf
instead.
printf '%s\n' -e
This works with arbitrary variables:
var=-e
printf '%s\n' "$var"
...meaning you don't need to do any special preparation/modification elsewhere in your code based on the knowledge that a value will be echo
d.
Incidentally, the POSIX shell command specification for echo
acknowledges that it is unportable as implemented, and contains a note on that subject:
It is not possible to use echo portably across all POSIX systems unless both -n (as the first argument) and escape sequences are omitted.
The printf utility can be used portably to emulate any of the traditional behaviors of the echo utility as follows (assuming that IFS has its standard value or is unset):
The historic System V echo and the requirements on XSI implementations in this volume of POSIX.1-2008 are equivalent to:
printf "%b\n" "$*"
The BSD echo is equivalent to:
if [ "X$1" = "X-n" ] then shift printf "%s" "$*" else printf "%s\n" "$*" fi
New applications are encouraged to use printf instead of echo.
(Emphasis added).
That said, on GNU systems, an alternative exists: Requesting standards-compliant behavior.
$ POSIXLY_CORRECT=1 /bin/echo -e
-e

- 1,732
- 15
- 22
-
Interestingly, the POSIX note does say that
echo -e
is portable. It says-n
must be avoided, and escape sequences must be avoided.echo -e
avoids both. But as you indicate in the last part of your answer, on GNU systems,echo
doesn't bother to conform to POSIX at all by default, and POSIX only notes portability across POSIX systems. – hvd Nov 16 '14 at 09:27 -
@hvd, I don't see
-e
covered in the portion of the spec that I linked to. Could you provide a link or citation that covers it? – Charles Duffy Nov 16 '14 at 16:53 -
It's the lack of a mention that says it. :) It lists the uses that aren't portable, and
-e
isn't mentioned, so-e
is portable (again, across POSIX systems). To be fair, what you quoted is informative, but the normative text says the same thing: "If the first operand is -n, or if any of the operands contain acharacter, the results are implementation-defined." – hvd Nov 16 '14 at 17:23 -
2@hvd, rather the contrary. To perform as specified,
echo
needs to emit all arguments with no behavior defined in a contrary way by the standard. Thus -- unlike almost all other command-line tools covered by the POSIX spec --echo
actually specifies behavior for arguments not given: Printing them. There is no room for adding new flags without breaking specification. – Charles Duffy Nov 16 '14 at 17:26 -
2@hvd, ...for that matter, see the
OPTIONS
section, where it's set out in black and white:Implementations shall not support any options
. – Charles Duffy Nov 16 '14 at 17:27 -
Yes, that's exactly what I meant. The OP is interested in printing the string "-e". On POSIX-conforming systems,
echo -e
does exactly that. – hvd Nov 16 '14 at 17:27 -
Sorry, then -- I quite misunderstood your argument; we are indeed in violent agreement. – Charles Duffy Nov 16 '14 at 17:28
-
I can see how my comments could be read the way you read them, sorry for not having been clearer. Glad it's resolved. :) – hvd Nov 16 '14 at 17:30
with newline
echo -en '-e\n'
without newline
echo -e '-e\c'
with spaces around:
echo '-e ' echo ' -e'
using backspace (thanks to Joseph R.):
echo -e ' \b-e'
(it does output SPC BS - e LF, but when sent to a terminal that's rendered as
-e
as BS moves the cursor back one column to the left causing-
to overwrite the SPC)
The behaviour of bash
's echo
builtin may depend on bash version. It also depends on the environment (POSIXLY_CORRECT
, SHELLOPTS
and BASHOPTS
variables), the options (posix
, xpg_echo
), the build options and argv[0]
(sh
vs bash
). Here tested with GNU bash 4.2.53(1)
, default build, default options, empty environment, invoked as bash
. Works also with zsh 5.0.5
.

- 544,893

- 47,140
-
3Why do these ugly-to-the-bone obfuscated "workarounds" receive upvotes? Charles Duffy below has the proper answer: use printf and forget about such problems once and for all. – Jens Nov 15 '14 at 18:25
-
-
7Jens: because the OP asked how to do it with the
echo
command. Attitude not necessary. – ctc Nov 15 '14 at 19:32 -
@ctc - What's the logic behind that answer? I'm not questioning whether it works (with the specific versions of
echo
tested), but it is a bit... interesting... given as NULs act as terminators when given in C strings; I'm curious as to whether it's an accident of implementation or defined behavior that it functions as given. – Charles Duffy Nov 17 '14 at 21:05 -
1
echo -e ' \b-e'
outputs space-backspace-dash-e. Only displayed in a terminal will it give you the illusion that it is dash-e. – Stéphane Chazelas Nov 30 '14 at 21:31 -
1@CharlesDuffy,
echo -e "\0-e"
does outputNUL-dash-e
. It's just that terminals ignore that NUL character (NULs even used to be sent to some terminals (that did not support flow control) to give them time to do other long things like a carriage return. See the section under Delays and Padding interminfo(5)
.) – Stéphane Chazelas Dec 01 '14 at 06:47 -
@StéphaneChazelas, ahh. I'm a touch disappointed that I read that incorrectly. That said, using this trick will have ill effects when emitting output anything but a terminal -- especially in cases (like shell command substitutions) where its output is stored in a C string. – Charles Duffy Dec 01 '14 at 14:06
With GNU echo
's -e
with the ASCII codes for the characters:
$ /bin/echo -e '\055'e
-e
055
is the octal ASCII number for -
(see man ascii
for quick reference).

- 72,889
-
1
/bin/echo
is indeed POSIX-specified. However, its interpretation of octal escape sequences is an XSI extension to the baseline specification. – Charles Duffy Nov 15 '14 at 19:36 -
@CharlesDuffy Indeed, I misspoke. +1 for printf (my first thought as well). Given that
-e
is an extension, however, is there a way to force pure POSIX behaviour onecho
? That would eliminate all uncertainty over this, I think. – muru Nov 15 '14 at 19:46 -
2Actually, yes! Exporting
POSIXLY_CORRECT=1
will result in POSIX-compliant behavior for GNU's/bin/echo
. – Charles Duffy Nov 16 '14 at 06:40 -
+1 Thanks, good to know to keep your scripts portable and "homebrew-Linux-independent" (i. e. also working on a pro workstation at work). – syntaxerror Dec 05 '14 at 20:57
-
-
With GNU
echo
, you can doPOSIXLY_CORRECT=1 /bin/echo -e
as POSIX currently requiresecho -e
to output-e<newline>
. – Stéphane Chazelas Feb 19 '19 at 10:30
While the obvious, standard and recommended solution is to use printf
, to do it with echo
can be quite tricky depending on the implementation (not as tricky as for -n
though).
POSIX.2017 compliant echo
s
POSIX requires echo -e
to output -e<newline>
. So it's just
echo -e
there. POSIX compliant echo
s in that regard (most of them are not POSIX compliant in other regards, the POSIX spec is close to useless when it comes to echo
) include:
- the
echo
builtin ofbash
when both thexpg_echo
andposix
options have been enabled (at runtime or build time like for the/bin/sh
of Apple macOS).set -o posix; shopt -s xpg_echo
(theposix
option can also be enabled if invoked assh
or whenPOSIXLY_CORRECT
orSHELLOPTS=posix
is in the environment). - the
/bin/echo
of certified UNIX systems (AIX, macOS, Solaris at least) and most BSDs - the
echo
builtin ofdash
,ksh88
, the Bourne shell, csh, tcsh, posh, rc, es, akanga - GNU
echo
(/bin/echo
on GNU systems) whenPOSIXLY_CORRECT
is in the environment. - the
echo
builtin ofmksh
and some other pdksh-derives when theirposix
option is enabled. - the
echo
builtin ofyash
when$ECHO_STYLE
is either unset or one ofSYSV
,XSI
,BSD
,DASH
,RAW
implementations that support -e
Includes echo
of research Unix V8 (where it comes from), GNU, busybox, the echo
builtin of bash
, zsh
, pdksh
and derivatives, fish
, some ash
-based shells like busybox sh
or the sh
of some BSDs, recent versions of ksh93
(on some systems, and with some values of $PATH
) with their default settings, yash
with $ECHO_STYLE
one of GNU
or ZSH
:
echo -e '-e\n\c'
The implementations that support -e
invariably support -n
, so:
echo -ne '-e\n'
would work as well.
zsh
zsh
's echo
is the only implementation that I know that supports an end-of-option marker (-
).
echo - -e
Making it the only Bourne-like shell echo
that can output arbitrary data (also because it's the only one that supports NUL bytes in its variables and the arguments of its builtins) with echo -E - "$data"
)
Except for the NUL-byte issue, other implementations that can output arbitrary data are FreeBSD or macOS /bin/echo
where you can do:
/bin/echo "$data
\c"
(in that implementation, \c
is only recognized at the end, and no other escape sequence is supported).
And yash
's:
ECHO_STYLE=RAW echo "$data"
(though note that yash
variables can only hold text, so not arbitrary byte sequences in locales where not all sequences of bytes can form valid characters like in those using UTF-8 as their charmap).

- 544,893
Use -n
to avoid newline:
$ echo -n - && echo e
-e

- 121
-
That won't work in
zsh
where-
is the end of option delimiter or on all theecho
implementations that don't support-n
(those that support-e
also support-n
though) – Stéphane Chazelas Feb 19 '19 at 10:27
echo
is usually a shell builtin, but there is usually also/usr/bin/echo
. The-e
is not POSIX, but available e.g. with bash. Please give more details what you mean with 'they still don't work'. What is the expected behavior? – maxschlepzig Nov 15 '14 at 10:21echo -- -e
doesn't work either. Conventionally (with GNU utilities at least) the double dash indicates the end of options, with the rest being kept as literal arguments. – Wil Cooley Nov 15 '14 at 16:47echo
by its nature needs to treat arguments as data, including those that start with dashes, each and every extension is by its nature a deviation from standard-defined behavior (something that a standards-compliantecho
would emit to the screen gracefully, but an extendedecho
does not). – Charles Duffy Nov 15 '14 at 17:23echo
madness again. If people would only useprintf
and never look back. – Jens Nov 15 '14 at 18:23