[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Changing the way bash expands associative array subscripts

From: Chet Ramey
Subject: Re: Changing the way bash expands associative array subscripts
Date: Sun, 18 Apr 2021 18:00:56 -0400
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0) Gecko/20100101 Thunderbird/78.9.1

On 4/16/21 12:11 PM, Koichi Murase wrote:

  From the users' point of view, indirect expansions and name references
currently undergo "double expansions" in assigning time and in
reference time; I mean naive users will write as « iref=a[$key] »
instead of « iref='a[$key]' » and run « echo "${!iref}" » to find that
the original right-hand side of the assignment is finally
double-expanded until the reference time.

That's the point of indirect expansions! Even in the most basic use case:

echo ${!v}

nobody should be surprised to see a `double expansion'.

In that case, I agree that no one would be surprised by the double
expansion of the *variable names* because it's the purpose of the
namerefs.  But I don't think everyone would necessarily expect the
*subscripts* would also be double-expanded.

In this instance, on the rhs of an assignment statement, there's no need to treat subscripts any different than any other part of the value string.
They have no semantic meaning there.

When used `normally', subscripts are expanded when expanding an array
element value (${a[key]}). I don't see any of this as inconsistent.

Yes, but if `unset' is defaulted to `assoc_expand_once' behavior while
indirect expansions and namerefs aren't changed, users still need to
do two different ways of quoting: « unset "a[$key]" » versus «
iref='a[$key]'; echo "${!iref}" » and « declare -n nref='a[$key]';
echo "$nref" ».

I just don't see this as the same problem you do. Assigning a string value
to a variable is not the same thing as expanding a variable's value.

In my point of view, indirect expansions and name references are also
the places where unintended word expansions (including command
substitutions) could be caused by naive users.  For example, something

key=$(< untrustworty-file.txt) # can be e.g. key='$(echo injected >&2)'
echo "${!iref}"

That's just bad code. You can't protect people from everything, and
sometimes you shouldn't try.

For the option `assoc_expand_once', I don't know a
perfectly consistent solution, but one of possible (incomplete) ways
might be treating 'assoc[@]' in many places as the single element
reference with `shopt -s assoc_expand_once':


I already answered this in a separate message. I don't think you need to
bring `assoc_expand_once' into it to change some of these cases.

Or another solution might be introducing special syntactic treatment
of `unset' arguments:

Nope, not going to go that way without much better reasons than I've seen
so far.

``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    chet@case.edu    http://tiswww.cwru.edu/~chet/

reply via email to

[Prev in Thread] Current Thread [Next in Thread]