[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
bin/52090: /bin/sh does not expand $* (or $@) when unquoted correctly
>Synopsis: /bin/sh does not expand $* (or $@) when unquoted correctly
>Arrival-Date: Sun Mar 19 03:30:00 +0000 2017
>Originator: Robert Elz
>Release: NetBSD 7.99.65 (irrelevant, applies to all versions)
System: NetBSD andromeda.noi.kre.to 7.99.43 NetBSD 7.99.43 (VBOX64-1.2-20161202) #21: Sat Dec 3 00:43:51 ICT 2016 kre%magnolia.noi.kre.to@localhost:/usr/obj/current/kernels/amd64/VBOX64 amd64
The rules for expanding an unquoted $* (or $@) are that they
produce 1 word for each set positional parameter.
From Posix sh standard, section 2.5.2
74866 * Expands to the positional parameters, starting from one,
initially producing one field for
74867 each positional parameter that is set.
(the margin numbers are the line numbers from the current version,
I wrapped the first line for this e-mail)
There are, of course, more details, but those aren't relevant here.
After those fields are produced, word splitting is (usually)
performed, on each of them in turn, possibly generating more
[aside: "field' is the term used for what we would thing of as a word,
or perhaps an arg, but is more precisely defined, and those other terms
are used with different meanings.]
What the NetBSD sh does is produce a single field, with the
positional parameters separated by IFS (the first char of $IFS)
When word splitting is done, the field is split at each IFS
character (and other IFS characters if they occur) so each
inserted IFS in the single field produced causes a new field
to appear in the final output.
It appears as if everything is just fine implementing it this
way (and it more or less is) -- except when IFS=''
Then the way the sh currently does it is simply to run all the
positional parameters together into a single string. Since there
are no chars in IFS, when word splitting is attempted nothing
happens. The result is a single field, where there should be
more one for each positional parameter.
An easy way to see this is
set a b c d ; # $# is 4, and $1 .. $4 are set
IFS= ; no chars in IFS
set $* ; set the args to whatever $* expands to
echo $# ; should produce 4
On NetBSD the final echo writes "1" rather than "4" as it should.
There were 4 positional parameters, therefore $* should produce 4
fields, each of which should be set back into the positional params
1 .. 4. Instead the NetBSD sh produces a single param "abcd"
Note that if $* were quoted ("$*") what we do now is correct, even
if it doesn't happen internally in quite the way envisaged.
Main Index |
Thread Index |