← Back to Bash Course | Chapter 13: Advanced Scripting | Lesson 4 of 7

Arrays of Arguments ("$@" vs "$*" Quoting Difference)

There are two ways to expand all of a script's arguments together, and one keeps each argument separate while the other glues them all into a single piece of text.

Quoted "$@" Preserves Separate Arguments

"$@" expands to each positional parameter as its own distinct, quoted word, so an argument containing spaces stays intact as a single item when iterated or forwarded.

Example: Quoted "$@" Preserves Separate Arguments

bash
#!/bin/bash
set -- "first arg" "second arg"
count=0
for a in "$@"; do
    count=$((count + 1))
    echo "arg $count: [$a]"
done

Quoted "$*" Joins Into One String

"$*" combines all positional parameters into a single string, separated by the first character of IFS (a space by default), losing the original boundaries between arguments.

Example: Quoted "$*" Joins Into One String

bash
#!/bin/bash
set -- "first arg" "second arg"
combined="$*"
echo "combined into one string: [$combined]"

Forwarding Arguments to Another Function

When one function needs to pass its own arguments through to another command exactly as received, "$@" is the correct choice because it preserves each argument's original boundaries, even with embedded spaces.

Warning: Forwarding with $* (or unquoted $@) instead of "$@" can silently merge or re-split arguments containing spaces.

Example: Forwarding Arguments to Another Function

bash
#!/bin/bash
show_each() {
    for a in "$@"; do
        echo "received: [$a]"
    done
}

forward_args() {
    show_each "$@"
}

forward_args "has space" "nospace"
Common Mistakes
  1. Assuming "$@" and "$*" behave the same; unquoted they're similar, but quoted they differ fundamentally.
  2. Using $* (unquoted or quoted) to forward arguments to another command, which can merge or mis-split arguments containing spaces.
  3. Forgetting "$@" expands to each positional parameter as its own separately-quoted word, which is almost always what you want when forwarding arguments.
Chapter Summary
  • "$@" expands to each positional parameter as a separate, individually-quoted word — the safe default for forwarding arguments.
  • "$*" expands to all positional parameters joined into a SINGLE string, separated by the first character of IFS.
  • Unquoted $@ and $* behave almost identically (both split on whitespace), so the difference only really matters when quoted.
  • Use "$@" when passing arguments through to another command; reserve "$*" for when you deliberately want one combined string.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.