1: glob
When I do echo \*
I get *
This seems right, as * is escaped and taken literally.
Yes, with an escape \
(quote), an otherwise special character becomes regular and therefore is printed back as it is, a *
.
But I can't understand that, when I do echo \\*
I get \*
Because you need to think about "an string" to expand (via globbing). The string is \\*
, which, because it is un-quoted and it has an special character (the backslash) the first backslash quotes the second and becomes one backslash followed by an asterisk (\*
). The string: backslash (\
) followed by anything (*
) should match literally that: a file name that start with a backslash and followed by more characters. If there are no files like \a
, \one
or \file
the globbing of \*
fails, that is, it can not expand to a "list of files". If some options in bash (failglob or nullglob) are not set, the string \*
remains and is printed as it was. You get \*
back.
2: concatenation
I was expecting:
$ echo \\*
\file1 file2 file3
Above we clarified why \\*
ends up being the string \*
, that is: one string. There is no concatenation of two strings as in:
$ a='\'
$ b='file1 file2 file3'
$ echo "$a$b"
/file1 file2 file3
That is:you need two strings to get them concatenated. One string could be a variable of the literal \
, the other could be the list of files in the present directory as an string. One way to accomplish that is:
$ set -- * # get the list of files as arguments.
$ echo '\'"$*" # or "\\$*". Convert arguments to an string $*
# and concatenate '\' to it.
\file1 file2 file3