383

What does a dollar sign followed by an at-sign (@) mean in a shell script?

For example:

umbrella_corp_options $@
0

8 Answers 8

427

$@ is all of the parameters passed to the script.

For instance, if you call ./someScript.sh foo bar then $@ will be equal to foo bar.

If you do:

./someScript.sh foo bar

and then inside someScript.sh reference:

umbrella_corp_options "$@"

this will be passed to umbrella_corp_options with each individual parameter enclosed in double quotes, allowing to take parameters with blank space from the caller and pass them on.

6
  • 3
    What would $@ contain if I did someScript.sh foo bar "boo far"?
    – trusktr
    Apr 3, 2012 at 14:02
  • 2
    teaching.idallen.com/dat2330/04f/notes/shell_variables.txt Check this out.
    – Har
    Apr 3, 2012 at 14:13
  • 11
    $@ is special if written in double quotes. Then it will result in a list of quoted values, in your case, trusktr, in the three arguments "foo", "bar", and "boo far".
    – Alfe
    Apr 3, 2012 at 14:28
  • 5
    Although it is generally the case, $@ does not necessarily come from paramaters passed to the script... eg; set a b "x   y"; printf '(%s)' "$@" outputs (a)(b)(x   y)
    – Peter.O
    Apr 3, 2012 at 14:37
  • 6
    I like Alfe's answer better because he gives the main difference between $@ and $*
    – donleyp
    Nov 30, 2017 at 4:41
213

$@ is nearly the same as $*, both meaning "all command line arguments". They are often used to simply pass all arguments to another program (thus forming a wrapper around that other program).

The difference between the two syntaxes shows up when you have an argument with spaces in it (e.g.) and put $@ in double quotes:

wrappedProgram "$@"
# ^^^ this is correct and will hand over all arguments in the way
#     we received them, i. e. as several arguments, each of them
#     containing all the spaces and other uglinesses they have.
wrappedProgram "$*"
# ^^^ this will hand over exactly one argument, containing all
#     original arguments, separated by single spaces.
wrappedProgram $*
# ^^^ this will join all arguments by single spaces as well and
#     will then split the string as the shell does on the command
#     line, thus it will split an argument containing spaces into
#     several arguments.

Example: Calling

wrapper "one two    three" four five "six seven"

will result in:

"$@": wrappedProgram "one two    three" four five "six seven"
"$*": wrappedProgram "one two    three four five six seven"
                             ^^^^ These spaces are part of the first
                                  argument and are not changed.
$*:   wrappedProgram one two three four five six seven
8
  • 4
    They are not the same, and the manpage is clear on the side-effects of $* using IFS—which is not necessarily space. (If they were the same, there would not be any point, other than compatibility perhaps, in offering both.)
    – jørgensen
    Apr 3, 2012 at 14:48
  • 12
    No they are not. And I said so two lines below: "The difference between the two ..." In order to get short sentences and raise readability the reader has to read more than one sentence before giving a verdict :-/
    – Alfe
    Apr 5, 2012 at 15:41
  • 4
    Alfe, Christoffer's insertion of that one word "nearly" made a hell of a difference, without sacrificing any terseness or readability. In fact I upvoted this answer (as opposed to the accepted one) exactly due to that subtle emphasis of the difference... -- before realizing that it was almost against your will! ;)
    – Sz.
    Mar 2, 2017 at 13:13
  • I think that word made a hell of a difference for the people who give a verdict right after reading the first sentence ;-) and it was never against my will. I would really like to write also for these people.
    – Alfe
    Mar 2, 2017 at 17:54
  • Very unclear. wrappedProgram "$*" -> separated by single spaces. but in your 2nd example they aren't separated by single spaces. Apr 4, 2018 at 13:50
69

These are the command line arguments where:

$@ = stores all the arguments in a list of string
$* = stores all the arguments as a single string
$# = stores the number of arguments

5
  • (The above inaccuracy mentioned by @iruvar was fixed.) May 17, 2019 at 2:21
  • 3
    What is "list" in this context?
    – Magnus
    Dec 11, 2020 at 14:31
  • 1
    "$@" is actually not a list of strings, but a list of arguments. Feb 5, 2021 at 20:27
  • 1
    Right but what is "list"?
    – GameKyuubi
    Feb 22, 2022 at 0:44
  • @GameKyuubi You can learn more about Lists (rather Arrays) here: gnu.org/software/bash/manual/bash.html#Arrays
    – user16328828
    Jun 15, 2022 at 3:04
19

Meaning.

In brief, $@ expands to the arguments passed from the caller to a function or a script. Its meaning is context-dependent: Inside a function, it expands to the arguments passed to such function. If used in a script (outside a function), it expands to the arguments passed to such script.

$ cat my-script
#! /bin/sh
echo "$@"

$ ./my-script "Hi!"
Hi!
$ put () { echo "$@"; }
$ put "Hi!"
Hi!

* Note: Word splitting.

The shell splits tokens based on the contents of the IFS environment variable. Its default value is \t\n; i.e., whitespace, tab, and newline. Expanding "$@" gives you a pristine copy of the arguments passed. Expanding $@ may not. More specifically, any arguments containing characters present in IFS might split into two or more arguments or get truncated.

Thus, most of the time what you will want to use is "$@", not $@.

18

The usage of a pure $@ means in most cases "hurt the programmer as hard as you can", because in most cases it leads to problems with word separation and with spaces and other characters in arguments.

In (guessed) 99% of all cases, it is required to enclose it in ": "$@" is what can be used to reliably iterate over the arguments.

for a in "$@"; do something_with "$a"; done
2
  • 5
    Your line can be written as: for a; do something_with "$a"; done ;-)
    – Alfe
    Apr 3, 2012 at 14:11
  • 1
    @Alfe I know;I just hat forgotten it. Think of it as for a in start_token "$@" end_token; do something_with "$a"; done :-)
    – glglgl
    Apr 3, 2012 at 14:39
13

From the manual:

@

Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word. That is, "$@" is equivalent to "$1" "$2" .... If the double-quoted expansion occurs within a word, the expansion of the first parameter is joined with the beginning part of the original word, and the expansion of the last parameter is joined with the last part of the original word. When there are no positional parameters, "$@" and $@ expand to nothing (i.e., they are removed).

0

$@ is basically use for refers all the command-line arguments of shell-script. $1 , $2 , $3 refer to the first command-line argument, the second command-line argument, third argument.

-1

They are often used to simply pass all arguments to another program

[root@node1 shell]# ./my-script hi 11 33 hi 11 33 [root@node1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.