Bash – Accessing bash command line args $@ vs $*

bashcommand-line-arguments

In many SO questions and bash tutorials I see that I can access command line args in bash scripts in two ways:

$ ~ >cat testargs.sh 
#!/bin/bash

echo "you passed me" $*
echo "you passed me" $@

Which results in:

$ ~> bash testargs.sh arg1 arg2
you passed me arg1 arg2
you passed me arg1 arg2

What is the difference between $* and $@?
When should one use the former and when shall one use the latter?

Best Solution

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