On 11/19/25 8:25 AM, Robert Elz wrote:

   | Once that inconsistency gets fixed, we can talk about what the `right'
   | behavior should be.

There's no real "right" here, those ${var/...} etc operators are
all extensions, and any use of $@ or $* with any of the operators
is also unspecified, so everyone gets to do what they want in
these cases.

Sure. So what makes the most sense?


   | > I also hesitate to imagine how
   | >       echo $(( $@ ))

   | Well, everyone (including the NetBSD sh), manages to display `11' when
   | given these two scripts.

Sure, as I said, all shells do it that way, I am just unable to find
even a suggestion in the standard that this way is how it it should be
done.

Maybe this is one of those places where the standard has too much inside
baseball: everyone "knows" how it's supposed to be done, so just do it that
way and don't make it explicit.


In the standard, if we had:

   | set -- a + b

Then it seems to me from reading it (once more!) that 3 words
should be generated for $(( $@ )) as:

        $(( a
        +
        b ))

I can see how that would be a valid interpretation.


Not so much, just two (actual) variants for your test, when
actually tested properly (not including a quite different form
of unspecified behaviour and assuming a particular implementation)

   | Given these four commands:
   |
   | set a b c; IFS=: o=${@-x}; printf '<%s>\n' "$o"
   | set a b c; IFS=: o="${@-x}"; printf '<%s>\n' "$o"
   | set a b c; IFS=: o=${@?x}; printf '<%s>\n' "$o"
   | set a b c; IFS=: o="${@?x}"; printf '<%s>\n' "$o"
   |
   | There's the bash/ksh93/mksh/SVR4.2 sh camp, which uses spaces (except mksh
   | errors on the `?' expansion); the dash/yash/zsh camp, which consistenly
   | uses `:';

Yes.

   | and the BSD sh camp, which uses spaces in the first command and
   | `:' in the rest.

No, it doesn't.   You'd see the problem if you reordered the commands,
or just repeat the first one again later.

It kind of does, but the variance is that the BSDs make different choices
for unspecified behavior than the other ash descendents.

Anyway, that reduces it to two behaviors (I don't count bosh any more,
since you can't ask the maintainer :-( ).


Again, other than the $* expansions without operators, all of this
is unspecified, so there's no "wrong" here - but I still believe that
treating $@ as if it were $* in all of the unspecified cases is better
(including in the case of simple unquoted $@ when field splitting happens -
where it is defined to behave identically to $* - the wording in the
standard is identical).

I'll take a look at this, see what it takes, but I'd have to make it
conditional on a shell option if I decided to change things. Even if it's
a niche case, there are still scripts out there depending on the existing
behavior.

ps: I have no idea why you decided to repeat the "set" and IFS=
parts of the test,

That's how the original report had them. I just iterated by changing the
operators (and removing `declare -p', of course).

Chet

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

Reply via email to