Accessing bash command line args $@ vs $*

The difference appears when the special parameters are quoted. Let me illustrate the differences:

$ set -- "arg  1" "arg  2" "arg  3"

$ for word in $*; do echo "$word"; done
arg
1
arg
2
arg
3

$ for word in $@; do echo "$word"; done
arg
1
arg
2
arg
3

$ for word in "$*"; do echo "$word"; done
arg  1 arg  2 arg  3

$ for word in "$@"; do echo "$word"; done
arg  1
arg  2
arg  3

one further example on the importance of quoting: note there are 2 spaces between "arg" and the number, but if I fail to quote $word:

$ for word in "$@"; do echo $word; done
arg 1
arg 2
arg 3

and in bash, "$@" is the "default" list to iterate over:

$ for word; do echo "$word"; done
arg  1
arg  2
arg  3

A nice handy overview table from the Bash Hackers Wiki:

Syntax Effective result
$* $1 $2 $3 … ${N}
$@ $1 $2 $3 … ${N}
"$*" "$1c$2c$3c…c${N}"
"$@" "$1" "$2" "$3" … "${N}"

where c in the third row is the first character of $IFS, the Input Field Separator, a shell variable.

If the arguments are to be stored, load them in an array variable.