4 Answers
4

They aren't the same. $* is a single string, whereas $@ is an actual array. To see the difference, execute the following script like so:

> ./test.sh one two "three four"

The script:

#!/bin/bash
echo "Using \"\$*\":"
for a in "$*"; do
echo $a;
done
echo -e "\nUsing \$*:"
for a in $*; do
echo $a;
done
echo -e "\nUsing \"\$@\":"
for a in "$@"; do
echo $a;
done
echo -e "\nUsing \$@:"
for a in $@; do
echo $a;
done

The four cases are:

Using "$*":
one two three four

Here, the parameters are regarded as one long quoted string. Unquoted:

Using $*:
one
two
three
four

The string is broken into words by the for loop.

Using "$@":
one
two
three four

This treats each element of $@ as a quoted string.

Using $@:
one
two
three
four

This treats each element as an unquoted string, so the last one is again split by what amounts to for three four.

You can review Bash Beginners Guide for more information. These to do pretty much the same thing with the difference of how it's separated:

$* - Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the IFS special variable.

$@ - Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word.

But unless you set IFS to value other then default it could look identical.

If you use them without double quote, they are the same. There is no one preferred over the other in this case. But I suggest you to always use them with double quote, except you know what exactly you want.