I stumbled by accident on the following bash
behaviour, which is for me kind of unexpected.
# The following works
$ declare bar=Hello # Line 1
$ declare -p bar # Line 2
declare -- bar="Hello"
$ foo=bar # Line 3
$ declare ${foo}=Bye # Line 4
$ declare -p bar # Line 5
declare -- bar="Bye"
# The following fails, though
$ declare -a array=( A B C ) # Line 6
$ declare -p array # Line 7
declare -a array=([0]="A" [1]="B" [2]="C")
$ foo=array # Line 8
$ declare -a ${foo}=([0]="A" [1]="XXX" [2]="C") # Line 9
bash: syntax error near unexpected token `('`
# Quoting the assignment fixes the problem
$ declare -a "${foo}=(A YYY C)" # Line 10
$ declare -p array # Line 11
declare -a array=([0]="A" [1]="YYY" [2]="C")
Since shell expansion
- Brace expansion
- Tilde expansion
- Parameter and variable expansion
- Arithmetic expansion
- Process substitution
- Command substitution
- Word splitting
- Filename expansion
is performed on the command line after it has been split into tokens (followed by quote removal) but before the final command is executed, I would not have expected line 9 to fail.
Which is the rationale behind it, that makes bash
not accept line 9? Or, said differently, what am I missing in the way line 9 is processed by bash
that makes it fail but makes line 10 succeed?
In any case, quoting is not always going to straightforwardly work and it would require extra attention in case the array elements are strings with e.g. spaces.
(
like it would if it appeared elsewhere, and leaves it to the next level, which may barf on something that isn't a name.set -x
and see the difference betweendeclare -a array=( B C )
,declare -a "array=( B C )"
,declare -a "array=(" B C ")"
and similar variants.bash
implementation sounds like it was worth asking this question :) ...I now get that the assignment is not recognised as such since it is not at the beginning of a simple command, but this is somehow expected, isn't it? I mean, what we call assignment is indeed an argument ofdeclare
or is it wrong to think in this way? Still I do not get the difference between line 4 and line 9.