I know that
echo -e is not an ordinary command. I have tried
echo '-e' and
echo \-e but they still don`t work.
echo -en '-e\n'
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
-eas BS moves the cursor back one column to the left causing
-to overwrite the SPC)
The behaviour of
echo builtin may depend on bash version. It also depends on the environment (
BASHOPTS variables), the options (
xpg_echo), the build options and
bash). Here tested with
GNU bash 4.2.53(1), default build, default options, empty environment, invoked as
bash. Works also with
The best solution is not to use
echo, but to use
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
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.
That said, on GNU systems, an alternative exists: Requesting standards-compliant behavior.
$ POSIXLY_CORRECT=1 /bin/echo -e -e
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
echo -e to output
-e<newline>. So it's just
there. POSIX compliant
echos in that regard (most of them are not POSIX compliant in other regards, the POSIX spec is close to useless when it comes to
bashwhen both the
posixoptions have been enabled (at runtime or build time like for the
/bin/shof Apple macOS).
set -o posix; shopt -s xpg_echo(the
posixoption can also be enabled if invoked as
SHELLOPTS=posixis in the environment).
/bin/echoof certified UNIX systems (AIX, macOS, Solaris at least) and most BSDs
ksh88, the Bourne shell, csh, tcsh, posh, rc, es, akanga
/bin/echoon GNU systems) when
POSIXLY_CORRECTis in the environment.
mkshand some other pdksh-derives when their
posixoption is enabled.
$ECHO_STYLEis either unset or one of
implementations that support
echo of research Unix V8 (where it comes from), GNU, busybox, the
echo builtin of
pdksh and derivatives,
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,
$ECHO_STYLE one of
echo -e '-e\n\c'
The implementations that support
-e invariably support
echo -ne '-e\n'
would work as well.
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).
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).