From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17011 invoked by alias); 22 Oct 2014 21:39:49 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 33511 Received: (qmail 21121 invoked from network); 22 Oct 2014 21:39:47 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,FROM_12LTRDOM autolearn=ham version=3.3.2 Date: Wed, 22 Oct 2014 13:52:02 -0700 (PDT) From: Bart Schaefer Reply-To: Bart Schaefer To: zsh-workers@zsh.org Subject: [austin-group] Re: clarification on $*/$@ In-Reply-To: <54480AFD.9010504@case.edu> Message-ID: References: <20141020215420.GB7819@chaz.gmail.com> <54480AFD.9010504@case.edu> User-Agent: Alpine 2.00 (LRH 1167 2008-08-23) X-Face: "f/X=UCVgd*^c>+x(gMq0at?e:woX+;'snkkRzc3SX<0AZ (/PS4.M2hzGS9X:Qj]at_H/%a9K}:-eS<"v_7vX84PG9Bf Zpb`wI!I4geY=or+nWq`3CX`oq&TJR;g^ps|7(MH?jh;bs %vHJfCh5>a*6Re5m|Bidja\\o]>n\A)ib1:yX*T`zR(*h~ %tOw<~!D9{e6h!8M2:d8G2@K>y^1I_Vdy\d\MYe]z7c MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Extensive quoting for context. On Wed, 22 Oct 2014, Chet Ramey wrote: > On 10/20/14, 5:54 PM, Stephane Chazelas wrote: > > > In the Bourne shell, $@ and $* were the same and were variables > > whose content was the concatenation of the positional > > parameters. > > > > The only thing special was "$@" ($@ quoted) in list contexts > > (like in arguments to simple commands or in for i in "$@"). > > > > So in: > > > > set a b@c > > IFS=:,@ > > printf '<%s>\n' $* > > > > $* expands to "a:b@c" and undergoes word splitting. > > Not really, if you meant how the historical Bourne shell behaved. The > Bourne shell expands it to "a b@c" and performs word splitting, resulting > in > > Hmm, zsh in sh-emulation behaves as Stephane describes: $ set a b@c $ IFS=:,@ $ printf '<%s>\n' $* $ printf '<%s>\n' "$*" > > set a b@c > > IFS= > > printf '<%s>\n' $@ > > > > $@ expands to one argument only: "a b@c" > > Yes, this is what the Bourne shell did/does. Hmm again, zsh: $ IFS= $ printf '<%s>\n' $@ $ unset IFS $ printf '<%s>\n' $@ > > ksh introduced the joining on the joining on the first character > > of IFS instead of a space character and arrays. $* and $@ still > > seem to contain the concatenation of the positional parameters > > with the first character of IFS except that in list contexts, > > unquoted $* and $@ are also split on the positional parameters > > > > set a b > > IFS= > > a=$@ > > > > assigns "ab" to $a, but > > That's not true: sh, ksh, bash, and so on assign "a b". If you meant to > use $*, you're correct. Only $* is specified to use the first character > of $IFS. Zsh joins all arrays on the first character of IFS in this context. Note that assignment is one of the few contexts in which an array is joined into a scalar. [[ ]] is another. $ set a b $ IFS= $ a=$@ $ print $a ab $ b=(b a) $ a=${b[@]} $ print $a ba $ [[ $@ = ab ]] && echo joined on IFS joined on IFS > If this is central to your argument, you might want to reframe it. Is this an incompatibility that we should consider fixing? > > set a b > > IFS= > > printf '<%s>\n' $@ > > > > expands to 2 arguments "a" and "b". > > Yes, ksh/mksh and bash do this. The historical Bourne shell expands it to > one argument: "a b". Zsh is as ksh here: $ set a b $ IFS= $ printf '<%s>\n' $@ > > So: > > > > IFS= > > set a b > > printf '<%s>\n' $@ > > > > would expand to one "ab" argument as you'd expect (as a logical > > continuation of the Bourne shell and to be consistent with > > a=$@ and from a shell that doesn't support arrays). > > One wouldn't. Only dash does this. Command-line arguments are not a context in which arrays are joined in zsh, either. Dash surprises me. > > bash behaviour is rather odd. In some places $@ and $* seem to > > be the concatenation of arguments with the first character of > > IFS, sometimes with space. > > > > $ bash -c 'set a b; IFS=; a="$@"; echo "$a"' > > a b > > $ bash -c 'set a b; IFS=; a=$*; echo "$a"' > > ab > > $ bash -c 'set a b; IFS=; a="a bc"; echo ${a#$*}' > > c > > Yes, the third case is a problem. The other two cases are consistent with > ksh93, mksh, and other Posix shells except dash. Zsh gives: % ARGV0=sh zsh -fc 'set a b; IFS=; a="$@"; echo "$a"' ab % ARGV0=sh zsh -fc 'set a b; IFS=; a=$*; echo "$a"' ab % ARGV0=sh zsh -fc 'set a b; IFS=; a="a bc"; echo ${a#$*}' a bc