[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: More fun with IFS
From: |
Dan Douglas |
Subject: |
Re: More fun with IFS |
Date: |
Wed, 30 Jan 2013 01:47:12 -0600 |
User-agent: |
KMail/4.8.3 (Linux/3.4.6-pf+; KDE/4.8.3; x86_64; ; ) |
On Wednesday, January 30, 2013 02:00:26 AM Chris F.A. Johnson wrote:
> On Wed, 30 Jan 2013, Dan Douglas wrote:
>
> > Hi everyone, and welcome to another edition of IBOTD (IFS-bug-of-the-day),
> > featuring everyone's favorite Bourne shell kludge: word-splitting!
> >
> > On today's episode - inconsistencies within assignments that depend upon
> > quoting. I can't take credit for discovering this -- it was pointed out
> > to me by some guys on IRC after demonstrating some other stuff.
> >
> > And a quick test:
> >
> > function expassign {
> > typeset -a a
> > a=("$@")
> > typeset var asn
> >
> > while IFS= read -r asn; do
> > IFS=: command eval "$asn"
> > printf '%-14s... %s\n' "$asn" "$var"
> > done <<\EOF
> > var=${a[*]}
> > var="${a[*]}"
> > var=$*
> > var="$*"
> > var=${a[@]}
> > var="${a[@]}"
> > var=$@
> > var="$@"
> > EOF
> > }
> >
> > ${ZSH_VERSION+:} false && emulate ksh
> > expassign one:::two three:::four
> >
> > Bash output: # I think...
> > var=${a[*]} ... one two three four # bad
>
> Looks good to me. It expands to multiple words, just as an unquoted
> $* would do.
No, $* always expands to a single word. If multiple words result, those are
the result of field-splitting, not an intrinsic multi-word expansion as in the
case of $@. Though POSIX says very little about the unquoted cases.
Secondly, at least one of these would almost have to be wrong unless it
somehow makes sense for $* and ${a[*]} to be treated differently (it doesn't).
Third, field-splitting doesn't occur within assignments so quoting shouldn't
matter here.
I'll grant that POSIX is extremely unclear about whether and when multiple
words are actually the result of a multi-word expansion, or a field splitting
step. It gets much worse when it comes to the alternate-value expansions where
it's then additionally unclear whether and how word-splitting and/or the
implicit multi-wordness of $@ occur recursively when nested (or not). Almost
all shells disagree on that, but I need to do more research for those cases
because it's hard to test what's going on. ksh93 is especially bizarre in its
nested expansions.
> > var="${a[*]}" ... one:::two:three:::four # good
> > var=$* ... one:::two:three:::four # good
> > var="$*" ... one:::two:three:::four # good
> > var=${a[@]} ... one two three four # bad
>
> As above.
No, the ::: shouldn't be removed here. The * and @ cases are separate issues
(I should have been clear that there are multiple problems going on).
> > var="${a[@]}" ... one:::two three:::four # good
> > var=$@ ... one two three four # bad
>
> Ditto.
>
> > var="$@" ... one:::two three:::four # good
> >
> > Zsh and pdkshes produce:
> >
> > one:::two:three:::four
> >
> > For all of the above, which I think is wrong for the last 4. ksh93
produces:
> >
> > one:::two three:::four
> >
> > for the last 4, which I think is correct.
> >
> >
>
>
--
Dan Douglas
Re: More fun with IFS, Chet Ramey, 2013/01/31