Discussion:
[Help-bash] Indirect variable assignment with declare
noone
2017-08-17 21:41:50 UTC
Permalink
I wonder if the behavior demonstrated below is legit or is it a bug?


arg='--src'
a='abc def'

declare src=$a
echo "src=[$src]" # src=[abc def]
declare src="$a"
echo "src=[$src]" # src=[abc def]

declare ${arg#--}=$a # <------ indirect assignment, no quotes
echo "src=[$src]" # src=[abc] <------ $a got expanded in declare above
declare ${arg#--}="$a"
echo "src=[$src]" # src=[abc def]


Output:

src=[abc def]
src=[abc def]
src=[abc]
src=[abc def]


So the only case declare required quotes on the right side of the
assignment is indirect assignment without quotes.

Does it work as supposed?


My bash version is 4.4.12 (= bash:latest from dockerhub).
Chet Ramey
2017-08-20 00:14:16 UTC
Permalink
Post by noone
I wonder if the behavior demonstrated below is legit or is it a bug?
It's legit.

`declare' and its siblings `local' and `typeset' (and its cousins `export'
and `readonly') are what Posix calls declaration builtins: arguments that
are determined to be assignment statements are expanded as if they were
assignment statements. Primarily this means no word splitting.

You can read the Posix discussion and interpretation at

http://austingroupbugs.net/view.php?id=351
Post by noone
arg='--src'
a='abc def'
declare src=$a
echo "src=[$src]" # src=[abc def]
declare src="$a"
echo "src=[$src]" # src=[abc def]
The arguments are both assignment statements, and that can be determined at
parse time. They do not undergo word splitting, so src is assigned the
unsplit value of $a.
Post by noone
declare ${arg#--}=$a # <------ indirect assignment, no quotes
echo "src=[$src]" # src=[abc] <------ $a got expanded in declare above
This is not a valid assignment statement at parse time, so it is not marked
as such and normal expansion, including word splitting, occurs. This means
that the command turns into

declare src=abc def

`declare' recognizes the assignment statement and performs it, and also
creates a new variable named `def' that has no value.
Post by noone
declare ${arg#--}="$a"
echo "src=[$src]" # src=[abc def]
The quotes around $a suppress word splitting.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU ***@case.edu http://cnswww.cns.cwru.edu/~chet/
Loading...