TL;DR: Use "$@" when you want to pass arguments unchanged to a function or program.
When you read the shell documentation you will see that there are two main ways to refer to all the arguments for passing to a function or program: $* and "$@". What is the difference? This test script will demonstrate it:
#!/bin/sh
testargs() {
echo testargs: $# arguments
showargs $*
showargs "$@"
}
showargs() {
echo showargs: $# arguments
for i
do
echo $i
done
}
testargs 1 2 3
testargs word 'quoted phrase' word
The result should be:
testargs: 3 argumentsAs you can see, the difference is manifest when an argument has whitespace. "$@" preserves the arguments, not parsing it again to break up at whitespace in arguments. Think if it as an idiom meaning pass arguments verbatim.
showargs: 3 arguments
1
2
3
showargs: 3 arguments
1
2
3
testargs: 3 arguments
showargs: 4 arguments
word
quoted
phrase
word
showargs: 3 arguments
word
quoted phrase
word
Why would you ever use $* though? Here's a place where you shouldn't use "$@".
su -c "$*" userIf you were to use "$@" and it contained multiple arguments, only the first argument would be used by -c and the others would follow, causing a syntax error. This however means that if you want to pass arguments with whitespace to -c, you have to quote them and escape the quotes too.