Difference between $* and $@ in Shell

In one of our earlier articles, we saw the different positional parameters in a shell script. We discussed about the positional parameter $*. There is one more positional parameter, $@, the definition of which is also the same as $*. Let us see in this article the exact difference between the parameters $* and $@.


First, let us write a simple shell script to understand $@:

$ cat cmd
#!/usr/bin/bash

echo "The total no of args are: $#"
echo "The \$* is: $*"
echo "The \$@ is: $@"

On running the above program with some command line arguments:

$ ./cmd 1 2 3
The total no of args are: 3
The $* is: 1 2 3
The $@ is: 1 2 3

As shown in the above output, both the $* and $@ behave the same. Both contain the command line arguments given.

Let us now write a script which exactly shows the difference:

$ cat cmd
#!/usr/bin/bash

echo "Printing \$* "
for i in $*
do
echo i is: $i
done

echo "Printing \$@ "
for i in "$@"
do
echo i is: $i
done

Now, on running the above script:

$ ./cmd a b "c d" e
Printing $*
i is: a
i is: b
i is: c
i is: d
i is: e
Printing $@
i is: a
i is: b
i is: c d
i is: e

In the above example, we write a for loop and display the arguments one by one using $* and $@. Notice the difference. When we pass the command line argument in double quotes("c d"), the $* does not consider them as a single entity, and splits them. However, the $@ considers them as a single entity and hence the 3rd echo statement shows "c d" together. This is the difference between $* and $@.