echo \\* - bash backslash escape behavior, is it evaluated backwards?
If you don't have a file in the current directory whose name starts with a backslash, this is expected behaviour. Bash expands *
to match any existing file names, but:
If the pattern does not match any existing filenames or pathnames, the pattern string shall be left unchanged.
Because there was no filename starting with \
, the pattern was left as-is and echo
is given the argument \*
. This behaviour is often confusing, and some other shells, such as zsh
, do not have it. You can change it in Bash using shopt -o failglob
, which will then give an error as zsh
does and help you diagnose the problem instead of misbehaving.
The *
and ?
pattern characters can appear anywhere in the word, and characters before and after are matched literally. That is why echo \\*
and echo \\ *
give such different output: the first matches anything that starts with \
(and fails) and the second outputs a \
, and then all filenames.
The most straightforward way of getting the output you want safely is probably to use printf:
printf '\\'; printf "%s " *
echo *
is unsafe in the case of unusual filenames with -
or \
in them in any case.