I'm struggling with Bash variable expansion. Please see the following code:
~/tmp 689$ a=~/Library/Application\ *; echo $a
/Users/foo/Library/Application *
~/tmp 690$ echo ~/Library/Application\ *
/Users/foo/Library/Application Scripts /Users/foo/Library/Application Support
As the order of expansion is brace->tilde->parameter->....->pathname,
why is pathname expansion not applied to $a
in the same way that it is in the 2nd command?
[added]
Does whitespace escaping have hidden behaviour regarding the following output?
~/tmp 705$ a=~/Library/Application*; echo $a
/Users/foo/Library/Application Scripts /Users/foo/Library/Application Support
To do what you meant to do, you'd have to use the following:
As for why your code didn't work:
In the context of variable assignment involving only literals or string interpolation (references to other variables), NO pathname expansion takes place, even with unquoted strings (e.g.,
a=*
,a="*"
, anda='*'
all assign literal*
)[1].(By contrast, pathname expansion is applied to unquoted strings inside an array definition (e.g.,
a=(*)
, or inside a command substitution (e..g,a=$(echo *)
).)Thus, the literal content of
$a
is/Users/foo/Library/Application *
Executing
echo $a
- i.e., NOT double-quoting the variable reference$a
- then applies word splitting and does the following:'/Users/foo/Library/Application'
(the 1st word - no expansion applied, due to its contents)*
(the 2nd word - i.e., it expands to matching filenames in the current dir.)The fact that the latter results in
*
in your case implies that you happen to be running theecho
command from an empty directory (save for hidden files, assuming the default configuration).[1]Whether the string is unquoted or not does, however, matter with respect to tilde expansion; e.g.,
a=~
expands~
to the user's home directory, whereasa='~'
ora="~"
assign literal~
.