Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

special variable $@ and $*

92 views
Skip to first unread message

kaushal

unread,
Dec 5, 2009, 3:53:28 AM12/5/09
to kaushal...@gmail.com
Hi,

http://tldp.org/LDP/abs/html/internalvariables.html#APPREF

I did not understand the difference between $@ and $* special
variable.
Please explain me with an example.

$*

All of the positional parameters, seen as a single word
$@

Same as $*, but each parameter is a quoted string, that is, the
parameters are passed on intact, without interpretation or expansion.
This means, among other things, that each parameter in the argument
list is seen as a separate word.

still not fully understood. Please suggest with an example.

Thanks,

Kaushal

David W. Hodgins

unread,
Dec 5, 2009, 4:38:17 AM12/5/09
to
On Sat, 05 Dec 2009 03:53:28 -0500, kaushal <kaushal...@gmail.com> wrote:

> I did not understand the difference between $@ and $* special

> Please explain me with an example.

#!/bin/bash
# saved as ~/bin/parmdiff
showparms () {
count=0
for parm in "$*"; do
(( count++ ))
echo "count=$count, parm=$parm"
done
count=0
for parm in "$@"; do
(( count++ ))
echo "count=$count, parm=$parm"
done
}
showparms firstparm "secondparm thirdparm"

$ parmdiff
count=1, parm=firstparm secondparm thirdparm
count=1, parm=firstparm
count=2, parm=secondparm thirdparm

Regards, Dave Hodgins

--
Change nomail.afraid.org to ody.ca to reply by email.
(nomail.afraid.org has been set up specifically for
use in usenet. Feel free to use it yourself.)

Jon LaBadie

unread,
Dec 5, 2009, 12:25:32 PM12/5/09
to

Suppose you run "your_script" as follows:

$ your_script one 'two three' 'four five'

where argument 2 has one space and arg3 has 4,
and suppose your_script contains:

cmd $* # 1)
cmd $@ # 2)
cmd "$*" # 3)
cmd "$@" # 4)


Then 1) receives 5 arguments, no spaces,
i.e. each word from the three args is an arg to cmd
2) receives 5 arguments, no spaces,
ditto
3) receives 1 argument and six spaces,
i.e. one big argument
4) receives 3 arguments and five spaces,
i.e. the original args

Seebs

unread,
Dec 5, 2009, 2:03:01 PM12/5/09
to
set -- a b
for i in "$*"
do
echo $i
done

=> "a b"

for i in "$@"
do
echo $i
done

=> "a
b"

-s
--
Copyright 2009, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

Chris F.A. Johnson

unread,
Dec 5, 2009, 4:53:56 PM12/5/09
to

$* and $@ are identical. They expand to each word on the command line.

"$*" and "$@" differ. The former is a single argument containing
all the arguments on the command line. The latter expands to each
argument on the command line.

As an example, the sa function prints all arguments on the command
line in 4 different ways: using $*, $@, "$*" and "$@". Each
argument is printed on a separate line.

$ sa()
{
printf "%s\n" 'Using $*:' $* \
'Using $@:' $@ \
'Using "$*":' "$*" \
'Using "$@":' "$@"
}
$ sa 1 '2 3' 4 ## 3 arguments containing 4 words
Using $*:
1
2
3
4
Using $@:
1
2
3
4
Using "$*":
1 2 3 4
Using "$@":
1
2 3
4


--
Chris F.A. Johnson, author <http://shell.cfajohnson.com/>
===================================================================
Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)
===== My code in this post, if any, assumes the POSIX locale =====
===== and is released under the GNU General Public Licence =====

Stephane CHAZELAS

unread,
Dec 6, 2009, 4:58:11 AM12/6/09
to
2009-12-5, 21:53(+00), Chris F.A. Johnson:

> On 2009-12-05, kaushal wrote:
>> Hi,
>>
>> http://tldp.org/LDP/abs/html/internalvariables.html#APPREF
>>
>> I did not understand the difference between $@ and $* special
>> variable.
>> Please explain me with an example.
>>
>> $*
>>
>> All of the positional parameters, seen as a single word
>> $@
>>
>> Same as $*, but each parameter is a quoted string, that is, the
>> parameters are passed on intact, without interpretation or expansion.
>> This means, among other things, that each parameter in the argument
>> list is seen as a separate word.
>>
>> still not fully understood. Please suggest with an example.
>
> $* and $@ are identical. They expand to each word on the command line.

That's one way to put it, that doesn't work in every shell.
Another way to put it is that $* and $@ are variables whose
content is the concatenation of the positional parameters (with
spaces for the Bourne shell and with the first character of $IFS
for the modern Bourne-like shell). They expand like every other
variable. The only special expansion is for $@ within double
quotes where a list of words/arguments is expected (like in
arguments to simple commands or in for loops...) where it is
expanded to the exact list of positional parameters. That's how
the Bourne shell, ash and zsh (in sh emulation) work (with
most versions of the Bourne shell though, "$@" expands to one
empty argument instead of no argument at all though when $# is
0).

Now with other shells, there are a few oddities/differences.

~$ bash -c 'IFS=; printf "<%s>\n" $@' sh a b
<a>
<b>
~$ pdksh -c 'IFS=; printf "<%s>\n" $@' sh a b
<a b>
~$ ksh93 -c 'IFS=; printf "<%s>\n" $@' sh a b
<a>
<b>
~$ bash -c 'IFS=:; a=$*; b=$@; echo "$a,$b"' sh a b
a:b,a b
~$ ksh93 -c 'IFS=:; a=$*; b=$@; echo "$a,$b"' sh a b
a:b,a b
~$ pdksh -c 'IFS=:; a=$*; b=$@; echo "$a,$b"' sh a b
a:b,a:b
~$ ash -c 'IFS=:; a=$*; b=$@; echo "$a,$b"' sh a b
a:b,a:b
~$ bash -c 'IFS=; a=$*; b=$@; echo "$a,$b"' sh a b
ab,a b
~$ ksh93 -c 'IFS=; a=$*; b=$@; echo "$a,$b"' sh a b
ab,a b
~$ pdksh -c 'IFS=; a=$*; b=$@; echo "$a,$b"' sh a b
a b,a b
~$ bash/ksh93/pdksh -c 'IFS=; a="$@"; echo "$a"' sh a b
a b


That is for bash and ksh93, when not in list context, $@ (and
"$@") expands to the positional parameters concatenated with
spaces instead of the first character of IFS. pdksh behavior is
stranger and looks a bit bogus to me.

Last time I checked, POSIX wasn't clear about that.

To be portable (and to write sensible code anyway), $* and $@
should always be used in double quotes and "$@" should only be
used in list contexts (not in assignments, redirections,
${x#"$@"}...)

--
Stï¿œphane

0 new messages