From: Stephane CHAZELAS on
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