Frequently Asked Question

What is the difference between $@ and $*, and why is "$@" special?

Both $@` and `$* expand to the script's positional parameters, the arguments passed on the command line. Unquoted, they behave the same: each parameter becomes a word, subject to the usual word splitting. The difference appears when you double-quote them. "$@" expands to each parameter as a separate quoted word: a script called with ./run "hello world" foo sees "hello world" and foo as two distinct arguments, preserving the space inside the first. "$*" joins all parameters into one string with the first character of $IFS (usually a space) as separator, so the same call yields one argument "hello world foo".

In almost every situation where you want to forward your script's arguments to another command, command "$@"`, you want `"$@", with the quotes. Unquoted $@ would lose the embedded space; "$*" would mash everything into one argument. The same rule applies to functions: when proxying arguments through a wrapper function, inner "$@"` is the correct incantation. Treat plain `$@ and $* as almost always bugs; reach for "$@" by reflex.

Further reading and video