What is the difference between $* and $@
linux, shell, unix
Solution
There is no difference if you do not put `$*` or `$@` in quotes. But if you put them inside quotes (which you should, as a general good practice), then `$@` will pass your parameters as separate parameters, whereas `$*` will just pass all params as a single 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 behaviour that we generally want.
More detailed description:
Case 1: No quotes around `$*` and `$@`:
Both have same behaviour.
`./bar.sh $*` => `bar.sh` gets `arg1`, `arg2` and `arg3` as separate arguments
`./bar.sh $@` => `bar.sh` gets `arg1`, `arg2` and `arg3` as separate arguments
Case 2: You use quotes around `$*` and `$@`:
`./bar.sh "$*"` => `bar.sh` gets `arg1 arg2 arg3` as a single argument
`./bar.sh "$@"` => `bar.sh` gets `arg1`, `arg2` and `arg3` as a separate arguments
More importantly, `$*` also ignores quotes in your argument list. For example, if you had supplied `./foo.sh arg1 "arg2 arg3"`, even then:
`./bar.sh "$*"` => `bar.sh` will still receive `arg2` and `arg3` as separate parameters!
`./bar.sh "$@"` => will pass `arg2 arg3` as a single parameter (which is what you usually want).
Notice again that this difference occurs only if you put `$*` and `$@` in quotes. Otherwise they have the same behaviour.
Official documentation: http://www.gnu.org/software/bash/manual/bash.html#Special-Parameters
Problem
Who can simply explain - what is the difference between $* and $@? - Why there are two variables for same content as above?