75

In shell scripts, what is the difference between $@ and $*?

Which one is the preferred way to get the script arguments?

Are there differences between the different shell interpreters about this?

1
  • From: shellscript.sh/variables2.html ,The variable $@ is all parameters $1 .. whatever. The variable $*, is similar, but does not preserve any whitespace, and quoting, so "File with spaces" becomes "File" "with" "spaces". Commented Jan 25, 2020 at 17:20

3 Answers 3

84

From here:

$@ behaves like $* except that when quoted the arguments are broken up properly if there are spaces in them.

Take this script for example (taken from the linked answer):

for var in "$@" do echo "$var" done 

Gives this:

$ sh test.sh 1 2 '3 4' 1 2 3 4 

Now change "$@" to $*:

for var in $* do echo "$var" done 

And you get this:

$ sh test.sh 1 2 '3 4' 1 2 3 4 

(Answer found by using Google)

Sign up to request clarification or add additional context in comments.

3 Comments

"$*" has one other interesting property. Each argument is separated by the value $IFS instead of a space.
It may be worthwhile to explain how the substitutions end up expanded (what the commands look-like afterwards) and why it results in the differing results.
Seeing this answer in the year 2024 is helpful and funny. Saying "Just search <term> with Google" with the proliferation of AI responses that can hallucinate nonsensical answers was such an unforeseeable problem back in 2010 when this answer was first written. That said, still finding this helpful 14 years later, so thank you kind stranger!
27

A key difference from my POV is that "$@" preserves the original number of arguments. It's the only form that does. For that reason it is very handy for passing args around with the script.

For example, if file my_script contains:

#!/bin/bash main() { echo 'MAIN sees ' $# ' args' } main $* main $@ main "$*" main "$@" ### end ### 

and I run it like this:

my_script 'a b c' d e 

I will get this output:

MAIN sees 5 args

MAIN sees 5 args

MAIN sees 1 args

MAIN sees 3 args

3 Comments

Pls, can you explain the 3rd output?
I assume you mean the one that encloses the dollarsign and star inside the double quotes. The double quotes 'gather' the args into a single string, namely 'a b c d e'. In addition the double quotes allow the evaluation of the dollarsign+star. (If you use single quotes around the dollarsign+star, you will get just the literal value '$*' - the shell will not expand the dollarsign+star expression.
I suggest you run the script, adding 5 lines (for $1, $2, ...$5) like the following to print the args seen by the main function: echo ' $1 is ' $1
2

With $@ each parameter is a quoted string. Otherwise it behaves the same.

See: http://tldp.org/LDP/abs/html/internalvariables.html#APPREF

2 Comments

"Is a quoted string"? That implies that using "$@" first generates a quoted string, and then that the shell then parses it on deciding how to run the next command. It would be more accurate to say that the string concatenation done by $* is skipped, as is the string-splitting done when $* is used unquoted. Thus, using "$@" is not only usually more correct, but it also is less work for the shell to interpret.
...by the way, to quote !abs in irc://irc.freenode.org/#bash -- The infamous "Advanced" Bash Scripting Guide should be avoided unless you know how to filter out the junk. It will teach you to write bugs, not scripts. In that light, the BashGuide was written: mywiki.wooledge.org/BashGuide

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.