2026年1月3日(土) 8:17 Greg Wooledge <[email protected]>:
> On Fri, Jan 02, 2026 at 17:24:46 -0500, Chet Ramey wrote:
> > On 12/31/25 6:58 PM, Koichi Murase wrote:
> > > My request is essentially to defer the
> > > identification of keys and values in non-subscripted forms after shell
> > > expansions (while keeping the identification between subscripted vs
> > > non-subscripted forms of lexical words to be performed before shell
> > > expansions).
> >
> > OK, you want a new feature.

Yes, essentially.

> > Since this is not compatible with previous
> > behavior, and since bash has never behaved this way, how should this new
> > feature be exposed?
> >
> > Should there be a shell option that changes the expansion behavior?
> > Some new assignment syntax? Something else?
>
> We're talking about this, right?
>
>     assoc=( "${kv[@]}" )
>
> Currently, the behavior makes no sense at all (from a script writer's
> point of view), so I have a hard time believing anyone's using it
> intentionally.

Honestly, I have the same feeling as Greg.

Although Chet mentioned that the kv-pair was introduced "primarily to
avoid the parsing and quoting difficulties involved in finding the end
of the subscript", I'm currently unsure about how it is difficult for
the current specific case for « [<key>]=<value> » in the compound
list. I agree that the identification of the end of the subscript
becomes an issue in a context where « [<key>]=<value> » is passed as a
"string", such as « ((assoc[$key]=value)) », « declare -n
nref="assoc[$key]" », and « unset "assoc[$key]" ». However, the
construct « [<key>]=<value> » in the compound list can be identified
at the parsing time (before the expansion of $key is performed). The
identification seems unambiguous, just as the normal assignment «
assoc[$key]=$value » as a simple command is unambiguous. Then, I
cannot stop doubting that anyone actually uses « assoc=($key $value) »
as a "better" version of « assoc=([$key]=$value) ». Users can simply
continue to use the traditional form « assoc=([$key]=$value) » or «
assoc=(["$key"]="$value") », and there seems to be no actual benefit
to using « assoc=($key $value) », introducing compatibility issues
with Bash < 5.1.

Even if users intentionally use the feature, users are likely to quote
the words the same as they quote the words for indexed arrays, i.e., «
assoc=("$key" "$value") » instead of « assoc=($key $value) » and «
assoc=(key "${values[*]}") » instead of « assoc=(key "${values[@]}")
». Writing « assoc=($key $value) », expecting that $key and $value
won't be word-split, seems unlikely. As far as the user quotes the words
as if they were for indexed arrays, the script is unaffected even if
we change the default expansion behavior of non-subscripted forms in
the compound list for associative arrays. For this reason, I believe
the impact is limited.

However, at the same time, we have learned in many discussions on this
mailing list that, once a feature is introduced, someone might be
using it. I suggest the following:

1. Change the default expansion behavior of non-subscripted forms in
the compound list for associative arrays.
2. Introduce a shopt option to reproduce the expansion behavior of
Bash <= 5.3 (or provide it through BASH_COMPAT=5.3).

> Whether the user intended to produce an array with keys 'foo' and 'baz'
> or an array with the single key '[foo]=bar' the point is neither of
> these things happens.
>
> [...]
>
> On the other hand, some script writers may expect bash to scan the
> first element of the list to see whether it matches the form [x]=y
> and if so, parse it as a key/value pair.  In that case, they may also
> expect every element to be scanned that way, or they may expect the
> first element's format to indicate the type of parsing that's used for
> all elements.
>
> I don't have a good idea for how to reconcile those two (or three)
> expectations.  Perhaps Koichi Murase does.

I believe « assoc=('[2]=value1' '[4]=value2') » should cause «
assoc=(['[2]=value1']='[4]=value2')» (instead of « assoc=([2]=value1
[4]=value2) ») to be consistent with the behavior of indexed arrays.
In fact, the assignment « indexed=('[2]=value1' '[4]=value2') » for an
indexed array doesn't try to parse "an assignment-like string inside
values", even though the indexed arrays accept the index-value pairs
in the compound list as « indexed=([2]=value1 [4]=value2) ».  This is
the same as « $(echo 'var=value1') » doesn't try to assign a value
`value1' to a variable `var' but tries to execute a command named
`var=value1'.  The assignment forms of constructs have always been
identified during parsing time, but not after expansions (except for
the case where parsing happens again after expansions such as « let
"assoc[$key]=1" »).  Shell beginners might expect «
indexed=('[2]=value')» to cause « indexed=([2]=value) » and « $(echo
'var=value1') » to cause « var=value1 », but we cannot be consistent
with such a naive expectation by beginners.

--
Koichi

Reply via email to