It makes no difference if you do not quote $* or $@ . But if you put them in quotation marks (which follows, as a general good practice), then $@ will pass your parameters as separate parameters, while $* will just pass all the parameters as one parameter.
Take these scripts ( foo.sh and bar.sh ) for testing:
>> cat bar.sh echo "Arg 1: $1" echo "Arg 2: $2" echo "Arg 3: $3" echo >> cat foo.sh echo '$* without quotes:' ./bar.sh $* echo ' $@ without quotes:' ./bar.sh $@ echo '$* with quotes:' ./bar.sh "$*" echo ' $@ with quotes:' ./bar.sh " $@ "
Now this example should make everything clear:
>> ./foo.sh arg1 "arg21 arg22" arg3 $* without quotes: Arg 1: arg1 Arg 2: arg21 Arg 3: arg22 $@ without quotes: Arg 1: arg1 Arg 2: arg21 Arg 3: arg22 $* with quotes: Arg 1: arg1 arg21 arg22 arg3 Arg 2: Arg 3: $@ with quotes: Arg 1: arg1 Arg 2: arg21 arg22 Arg 3: arg3
Clearly, " $@ " gives the behavior that we usually want.
Detailed description:
Case 1: there are no quotes around $* and $@ :
Both have the same behavior.
./bar.sh $* => bar.sh takes arg1 , arg2 and arg3 as separate arguments
./bar.sh $@ => bar.sh takes arg1 , arg2 and arg3 as separate arguments
Case 2: you use quotation marks around $* and $@ :
./bar.sh "$*" => bar.sh takes arg1 arg2 arg3 as one argument
./bar.sh " $@ " => bar.sh takes arg1 , arg2 and arg3 as separate arguments
More importantly, $* also ignores the quotation marks in the argument list. For example, if you put ./foo.sh arg1 "arg2 arg3" , even then:
./bar.sh "$*" => bar.sh will still get arg2 and arg3 as separate parameters!
./bar.sh " $@ " => will pass arg2 arg3 as the only parameter (which you usually want).
Please note that this difference only occurs if you put $* and $@ in quotation marks. Otherwise, they have the same behavior.
Official Documentation: http://www.gnu.org/software/bash/manual/bash.html#Special-Parameters