34

Possible Duplicate:
What the difference between “$@” and “$*” in bash?

For years and on dozens of occasions, I have hesitated between the use of $* and $@ in shell scripts. Having read the applicable section of Bash's manpage over and over again, having tried both $* and $@, I more or less completely fail to understand the practical difference of application between the two variables. Can you enlighten me, please?

I have been using $* recently, but don't ask me why. I don't know why, because I don't know why $@ even exists, except as an almost exact synonym for $*.

Is there any practical difference?

(I personally tend to use Bash, but remain agnostic regarding the choice of shell. My question is not specific to Bash as far as I know.)

Community
  • 1
  • 1
thb
  • 13,796
  • 3
  • 40
  • 68
  • 1
    Searching for [$* $@](http://symbolhound.com/?q=%24%40+%24*) on SymbolHound finds a number of duplicates. Handy tool, that. – Chris Morgan Mar 28 '12 at 21:09
  • 1
    (Also, for example, http://stackoverflow.com/questions/3307672/whats-the-difference-between-and-in-unix, http://stackoverflow.com/questions/2761723/what-is-the-difference-between-and-in-shell-scripts, http://stackoverflow.com/questions/4491115/what-is-the-internal-processing-of-and.) – Chris Morgan Mar 28 '12 at 21:10
  • @ChrisMorgan: Confirmed on all points. SymbolHound does look handy. I hadn't known about it. Next time, I will search there first. Should I take some action to merge my question with the one you suggest? – thb Mar 28 '12 at 21:17
  • It certainly is hard finding things when Stack OVerflow's search engine doesn't cope with symbols. You decide what to do about this question. – Chris Morgan Mar 28 '12 at 21:25
  • @ChrisMorgan: I have voted to close my own question. – thb Mar 28 '12 at 21:34

3 Answers3

73

Unquoted, there is no difference -- they're expanded to all the arguments and they're split accordingly. The difference comes when quoting. "$@" expands to properly quoted arguments and "$*" makes all arguments into a single argument. Take this for example:

#!/bin/bash

function print_args_at {
    printf "%s\n" "$@"
}

function print_args_star {
    printf "%s\n" "$*"
}

print_args_at "one" "two three" "four"
print_args_star "one" "two three" "four"

Then:

$ ./printf.sh 

one
two three
four

one two three four
user1071136
  • 15,636
  • 4
  • 42
  • 61
FatalError
  • 52,695
  • 14
  • 99
  • 116
8

Consider:

foo() { mv "$@"; } 
bar() { mv "$*"; }
foo a b
bar a b

The call to foo will attempt to mv file a to b. The call to bar will fail since it calls mv with only one argument.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • Thank you. Are *$@* and *$\** then identical if used without quote marks? – thb Mar 28 '12 at 21:09
  • 3
    Without quotes, $@ and $* are identical. – William Pursell Mar 28 '12 at 21:14
  • 2
    Also, on some broken shells `"$@"` expands to an empty argument `""` if there are no positional parameters, rather than correctly expanding to nothing. So this trick has to be used: `${@+"$@"}` (if `$@` is nonblank, substitute `"$@"` else nothing) . If you ever see that, you will know why. – Kaz Mar 28 '12 at 21:55
  • I always used `${1+"$@"}`, which works the same as `${@+"$@"}`. Was glad to dump the silly construct... :-) – torek Mar 29 '12 at 07:34
6

Note also that "$@" is magic only when there's nothing else in the quotes. These are identical:

set -- a "b c" d
some_func "foo $*"  
some_func "foo $@"

In both cases, some_func receives one argument.

glenn jackman
  • 238,783
  • 38
  • 220
  • 352