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 zsh
echo
builtin implementation, \
sequences (like \n
, \c
, \61
, \\
...) 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).
Both zsh
and bash
echo
s support a (non-standard) -E
option to disable the expansions (not supported by bash
's if both the xpg_echo
and 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
command:
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 bash
doesn't.
In ksh and zsh, you can also do:
print -r - "$var"
To print arbitrary data as-is.
More details at:
echo "$( ... )"
at all? why can't you redirect the output directlymy-cmd > file.txt
? – steeldriver Oct 06 '19 at 19:26>
– ljleb Oct 06 '19 at 19:41my-cmd
produce its output? – NickD Oct 06 '19 at 20:25echo '<data>'
's it (with single quotes). – ljleb Oct 06 '19 at 20:28