Reputation: 4872
How to use Bash substitution in a variable declaration
Some of you may have read the aforementioned question but I have been left with more questions than answer. I tried googling how bash tokenizing -> expansion works in detail but did not find the right answers.
Let's look at simple example:
q="www"
e=$q{.,.,.}
echo $e
#outputs: www{.,.,.}
Now this does not work as I would expect. Especially since echo $q{.,.,.}
outputs www. www. www.
as I would expect. There have been some sugestions in the first SO question to write stuff like set $q{.,.,.,1} & s="$@" & echo $s
This does work in the terminal but for some reasons when entered in a .sh script it outputs www{.,.,.}
Why is there a different behaviour between the script and the terminal and how to make sure to trigger the expansion?
Also, why does q=*
trigger pathname expansion but q={.,.,.}
does not trigger braces expansion?
Upvotes: 0
Views: 51
Reputation:
Words in the right-side of an assignment do not: "Brace Expand"
From "man bash" (emphasis mine):
A variable may be assigned to by a statement of the form
name=[value]
All values undergo tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal
There is no mention of "Brace Expansion", "Pathname expansion" or "splitting".
To get "Brace expansion" make it a command line (note that "$q"
is quoted):
$ q="www"
$ e="$( echo "$q"{.,.,.} )"
$ echo "$e"
www. www. www.
Or if you want an array (s asked in the linked question), use directly:
$ e=( "$q"{.,.,.} )
$ printf '<%s> ' "${e[@]}"; echo ### No, `$e` is not enough.
<www.> <www.> <www.>
why does q=* trigger pathname expansion
No, it doesn't:
$ a=* ; echo "$a"
*
Of course, an unquoted $a
will undergo pathname expansion, try:
$ a=* ; echo $a
Upvotes: 1
Reputation: 84343
To do what you want, you need to assign e as an array. You can then use array expansion to view the contents in the way you expect. Consider the following:
q="www"
e=( $q{.,.,.} )
echo "${e[@]}"
www. www. www.
Upvotes: 2
Reputation: 246774
bash performs expansion in a defined order, and brace expansion happens before parameter expansion.
When bash sees echo $e
, there are no brace expansions to perform. After the parameter expansion, bash does not go back to the prior ones.
If you need this, you can do one of:
e=$(echo $q{.,.,.}); echo "$e"
e=$q{.,.,.}; eval echo "$e"
Upvotes: 1