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