How do echo
and printf
treat backslashes in zsh
, bash
and other shells?
Under zsh I get the following behavior:
$ echo "foo\bar\baz"
foaaz
$ echo "foo\\bar\\baz"
foaaz
$ echo 'foo\bar\baz'
foaaz
$ echo 'foo\\bar\\baz'
foo\bar\baz
Under bash, things seem a bit more consistent:
bash$ echo "foo\bar\baz"
foo\bar\baz
bash$ echo 'foo\bar\baz'
foo\bar\baz
bash$
But more concretely: How can I pass a string containing backslashes such as \\foo\bar\something
to:
echo
printf
print
and get exactly the same string? (in zsh
and bash
)?
Here is another experiment with functions in zsh:
function foo
{
echo -E '$1'
}
$ foo \\here\is\some\path
$1
How can I have it just print \\here\is\some\path
?
Update (Note: this has now been answered in Stephane's comment)
I have tried the following in zsh 5.0.2:
function foo
{
printf '$s\n' $1
}
foo '\\some\path'
But this prints $s
?
Best Answer
zsh
echo
behaves the standard way, likebash
in UNIX mode. That is it expands\b
to the ASCII BS character as the UNIX specification requires.Don't use
echo
to display arbitrary strings, useprintf
:print -r -- "$1"
also works but isksh
/zsh
specific.echo -E - "$1"
work withzsh
and I believe some BSDs.works in any Bourne-like shell even those from a few decades when there was no
printf
command but it spawn a new process, and is really not necessary nowadays as we now haveprintf
everywhere.And by the way, you need to escape backslashes on a shell command line as it's special to the shell (every shell but
rc
), so:foo \\foo\bar
would pass the"\foo\bar"
string tofoo
which can't reinvent the lost backslash back.