Arrays of Arguments ("$@" vs "$*" Quoting Difference)
In this page:
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
#!/bin/bash
set -- "first arg" "second arg"
count=0
for a in "$@"; do
count=$((count + 1))
echo "arg $count: [$a]"
done
Login to try C/C++/Java/PHP code in the editor
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
#!/bin/bash
set -- "first arg" "second arg"
combined="$*"
echo "combined into one string: [$combined]"
Login to try C/C++/Java/PHP code in the editor
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
#!/bin/bash
show_each() {
for a in "$@"; do
echo "received: [$a]"
done
}
forward_args() {
show_each "$@"
}
forward_args "has space" "nospace"
Login to try C/C++/Java/PHP code in the editor
- Assuming
"$@"and"$*"behave the same; unquoted they're similar, but quoted they differ fundamentally. - Using
$*(unquoted or quoted) to forward arguments to another command, which can merge or mis-split arguments containing spaces. - Forgetting
"$@"expands to each positional parameter as its own separately-quoted word, which is almost always what you want when forwarding arguments.
"$@"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 ofIFS.- 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.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first:
- getopts for Parsing Command-Line Flags
- Positional Parameters and shift
- Process Substitution in Practice (diff <(...) <(...))
- Arrays of Arguments ("$@" vs "$*" Quoting Difference)
- Nameref Variables (declare -n) for Passing Arrays by Reference
- Heredoc Templating (Generating a Config File from Variables)
- Default/Fallback Argument Handling