Date: Mon, 17 Nov 2025 16:28:56 -0500
From: Chet Ramey <[email protected]>
Message-ID: <[email protected]>
| This is easy enough to fix; the pattern expansion operators didn't know
| the expansion was taking place on the rhs of an assignment statement.
I assume that "taking place on the rhs of an assignment" you really mean
"taking place in a situation where field splitting will not occur".
If not, you're likely to have the same issue when those constructions
are used as the "word" in a case statement, or after a redirect operator.
(and anywhere else where field splitting doesn't happen by rule).
I also hesitate to imagine how
echo $(( $@ ))
is intended to be parsed (similarly $@ in a here doc, except that one
is probably to be treated as an operand of a redirect and so no field
splitting).
But field splitting does occur in the expansion of the words of a
command, so I assume the above should be intended to be parsed as
echo $(( $1 )) $(( $2 )) $(( $3 )) ...
except there's no shell that does that. With one exception, they all
expand the $@ there as if it were $* (forgetting the issue of what
separator to use, ie: assume that the first char of IFS is space) -
so I assume there's something in the standard I don't recall (right
now I don't have suitable access to check it) - or perhaps just should
be, such that even though the text inside a $(( )) is treated as if it
were double quoted (except that " is not special) that text is automatically
exempt from field splitting, even when being expanded in a context where
field splitting should happen.
The one exception is bosh, in which
set -- 1 2 3 4
echo $(( $@ ))
just prints "4" ... all other shells have "trouble" parsing "1 2 3 4"
as a valid arith expression, and error out instead. Since that behaviour
(bosh's) makes no sense at all, no matter how $(($@)) is intended to be
interpreted, I think we can simply ignore that.
Most of this is all unspecified though, expanding $@ in a context where
field splitting doesn't happen is generally unspecified, and shells can
do whatever they like, so assuming that inside $(( )) is such a context,
no-one can actually say that bosh is incorrect.
kre
ps: personally I think the sane behaviour (also easy to implement) is to
treat (always) $@ expansions in non-field-splitting contexts exactly as
if $* had been written (in all respects). But as above, it is unspecified,
probably because, most likely for histerical reasons, many shells ignore
IFS and just use a space as a separator for $@ in that context. Weird.
And I believe that even bosh is expanding $@ inside $(( )) as if it were
like $* - it just has a strange interpretation of what $(( n n n n ))
means (where n is any digit string, not necessarily the same one each time).
If there are an odd number of n's, that is an error, if an even number,
the value of the arith expr is the value of the final n. I'm not sure
I can explain that, but it is what appears to happen.