echo is a non-portable command whose behaviour varies across implementations, versions, their compile-time and runtime option and the environment.
In particular, you shouldn't use it if its first argument may start with
- (though zsh's builtin
echo is one of the rare implementations that can work around that) or if any argument contains backslash characters.
Specifically with the
echo builtin implementation,
\ sequences (like
\\...) are expanded (as required by POSIX+XSI, while POSIX without XSI leaves the behaviour unspecified) unless the
bsdecho option is enabled (disabled by default on most deployments), while for
bash they are only expanded when the
xpg_echo is enabled (disabled by default on most deployments).
echos support a (non-standard)
-E option to disable the expansions (not supported by
bash's if both the
posix options are enabled though).
Here, even though you could do:
echo -E '<some data...>\\<some other data...>' > file
Which would work OK in
zsh and in most deployments of
bash, it would be much better to use the standard
printf '%s\n' '<some data...>\\<some other data...>' > file
Whose behaviour in that case is completely specified by POSIX and works the same across all implementations.
Note that the
printf utility is a POSIX invention. Long before POSIX, the Korn shell's answer to that non-portable
echo mess-up was a new
print builtin and its
-r option to not expand
\x sequences and a
- to mark the end of options.
zsh does have a Korn-like
print builtin, but
In ksh and zsh, you can also do:
print -r - "$var"
To print arbitrary data as-is.
More details at: