Questions about either the shell builtin or `/bin/echo`. This tag should not be used if your question is simply about printing to the terminal, only apply it if your question is specific to the `echo` command.
echo prints its operands connected by space to stdout with a trailing new line, for example,
echo hello world ..'OVERFLOW!' gives
hello world ..OVERFLOW!.
echo command — either program or builtin — may be one of the commands that new shell users are most familiar with, and may also be one of the commands that get built into most non-POSIX shells with similiar functionality (e.g.
csh), and even got its name into other types of languages like PHP.
echo has its limitations. As in POSIX,
echo generates undefined results when the first operand is
-n, or any of the operands contains backslashes; while SUSv2 XCU explicitly defines
-n to be treated as a string and backslashes to be escaped in a C-like way. There are also extra options extended by some implementations including GNU printf and bash, like
-e to enable backslash interpretation and
-E to explicitly disable it (default). With all the options, you should have already realized the consequences of
POSIX also makes this point clear:
It is not possible to use echo portably across all POSIX systems unless both -n (as the first argument) and escape sequences are omitted. [...]
New applications are encouraged to use printf instead of echo.
echo's printf replacement has been described in POSIX already, with examples for different
echo variants. The following is an example with support for
# Variant of http://www.etalabs.net/sh_tricks.html, mimics GNU & bash echo. # with the addition that one can use echo - "$var" to output the content # of $var verbatim (followed by a newline) like in zsh (but echo - still # outputs - unlike in zsh). echo() ( fmt=%s end='\n' IFS=' ' while [ $# -gt 1 ] ; do case "$1" in ([!-]*|-*[!neE]*) break;; esac # not a flag case "$1" in (*n*) end='';; esac # no newline case "$1" in (*e*) fmt=%b;; esac # interpret backslash escapes case "$1" in (*E*) fmt=%s;; esac # don't interpret backslashes shift done printf "$fmt$end" "$*" )
%b directive in printf works exactly as
echo -e does: it only interprets
Read more about this: