Bash, $@ and $* - unix1998/technical_notes GitHub Wiki

In Bash, $@ and $* are both used to represent all the positional parameters passed to a script or a function, but they behave differently, especially when quoted.

$@

  • When $@ is quoted ("$@"), each positional parameter is treated as a separate word.
  • For example, if the positional parameters are "one" "two three" "four", then "$@" will expand to:
    "one" "two three" "four"
    

$*

  • When $* is quoted ("$*"), all the positional parameters are treated as a single word, concatenated together with the first character of the IFS (Internal Field Separator) variable (by default a space).
  • Using the same example, if the positional parameters are "one" "two three" "four", then "$*" will expand to:
    "one two three four"
    

Unquoted $@ and $*

  • When unquoted, both $@ and $* behave similarly, expanding to a single string with all the positional parameters separated by the first character of IFS.

Practical Example

Here's a small script to demonstrate the differences:

#!/bin/bash

echo 'Unquoted $@:'
for arg in $@; do
  echo "$arg"
done

echo 'Unquoted $*:'
for arg in $*; do
  echo "$arg"
done

echo 'Quoted "$@":'
for arg in "$@"; do
  echo "$arg"
done

echo 'Quoted "$*":'
for arg in "$*"; do
  echo "$arg"
done

If you run the script with the parameters one "two three" four, you'll get:

Unquoted $@:
one
two
three
four

Unquoted $*:
one
two
three
four

Quoted "$@":
one
two three
four

Quoted "$*":
one two three four

In summary:

  • "$@" treats each argument separately.
  • "$*" treats all arguments as a single string.