Why does echo
interpret “n” as new line character in interactive shells only and not when executing a shell script also?
Running in an interactive bash
shell:
$ echo "hellonworld"
hello
world
Running as a script using bash
:
$ echo 'echo "hello\nworld"' > hello_world.sh
$ bash hello_world.sh
hellonworld
Running as a script using sh
:
$ sh hello_world.sh
hello
world
2
TLDR: interactive bash has a shell built-in echo
different from /usr/bin/echo
The utility which
can be used to show that echo
in an interactive bash command line is actually using the shell built-in echo command, rather than /usr/bin/echo
.
Since they behave differently regarding their interpretation of escape sequences, the output differs accordingly.
$ which -a echo
echo: shell built-in command
/usr/bin/echo
/bin/echo
/usr/bin/sh
is pointing to /usr/bin/dash
which does not have a shell built-in for echo and uses /usr/bin/echo
instead, so this explains the difference in behavior when running the script using sh
over bash
.
$ which -a echo
/usr/bin/echo
/bin/echo
By default, the external echo
command does not interpret the escape character and prints its arguments verbatim.
The -e
argument tells it to interpret the sequences that start with as special characters.
For speed optimisation, some shells provide internal implementations of echo
and these implementations may support different arguments and may have different default values for them.
It is also possible that the initialisation script of sh
(which is probably also executed by bash
) defines a function or an alias named echo
that delegates the work to the external or builtin echo
with the extra argument -e
.
1