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

Re: [OT] $*/$@/$IFS and Bourne vs Almquist vs Korn vs mksh



2014-10-15 16:19:00 +0200, Thorsten Glaser:
[...]
> tglase@tglase:~ $ dash -c 'IFS=; x=abc; printf "<%s>\n" ${x#$*}' x a b | sed -n l
> <a>$
> <abc>$
> tglase@tglase:~ $ ksh93 -c 'IFS=; x=abc; printf "<%s>\n" ${x#$*}' x a b | sed -n l
> <c>$
> tglase@tglase:~ $ mksh -c 'IFS=; x=abc; printf "<%s>\n" ${x#$*}' x a b | sed -n l
> <\a\300a>$
> <abc>$
> tglase@tglase:~ $ pdksh-5.2.14 -c 'IFS=; x=abc; printf "<%s>\n" ${x#$*}' x a b | sed -n l
> <abc>$
> 
> Makes you wonder if ksh93 gets it right, or if bash/pdksh do.
> But I agree that mksh’s output is just as broken as dash’s here.
[...]

The dash versions I have access to give the expected output
(same as your ksh93).

ksh93 has some other interesting bugs:

$ ksh -c 'IFS="*"; a=abcd; printf "<%s>\n" "$*" ${a##"$*"}' sh '' c
<*c>
<d>

bash and pdksh join the arguments with spaces. And there's
nothing in POSIX that allows them to do that.

But the problem is that that area is not covered by POSIX.

In the Bourne and Almquist shells, $* and $@ are normal
variables (except for $@ quoted in list contexts).

While for bash/ksh, they are array variables. POSIX fails to
pick a side here. They don't say that $* and $@ expansion are
not special other than that vague "expands to positional
arguments" which doesn't mean anything (and I can see dash has
just been updated so that unquoted $@ and $* expand to
positional arguments as separate words (still subject to
split+glob) in list context to match that vague requirement,
breaking consistency in the process).

And they don't say how those "arrays" are to be cast to scalars
when not in list context since they don't specify arrays in the
first place.

The non-list contexts include

a=$*
${a#$*}

case x in
  $a) ...;;
  "$a") ...
esac
${a#"$*"} # beware quotes also serve to cancel globs there

$(( $* ))
...

In any case, that's corner cases, not really ground for picking
one shell over the other for /bin/sh.

-- 
Stephane


Reply to: