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?

Original source