Comprehensive Analysis of $@ vs $* in Bash Scripting: Differences and Best Practices

Nov 23, 2025 · Programming · 8 views · 7.8

Keywords: Bash scripting | command-line arguments | parameter expansion

Abstract: This article provides an in-depth examination of the fundamental differences between $@ and $* special parameters in Bash scripting. It explores how quoting affects parameter expansion behavior through practical code examples, covering scenarios with spaced arguments, loop iterations, and array operations. The discussion includes IFS variable implications and guidelines for selecting appropriate parameter expansion methods to ensure script robustness.

Introduction

In Bash script programming, command-line argument handling is a fundamental and critical task. Many developers encounter the $@ and $* special parameters that appear similar at first glance. While both can access all positional parameters, they exhibit important differences in practical usage, particularly in scenarios involving quotes and parameter separation.

Basic Concepts and Surface Similarity

Let's first observe the similar behavior of $@ and $* when unquoted:

#!/bin/bash
echo "Using $*:" $*
echo "Using $@:" $@

When executing bash script.sh arg1 arg2, both produce identical output:

Using $*: arg1 arg2
Using $@: arg1 arg2

This surface consistency often leads beginners to believe the two are interchangeable.

Critical Differences Revealed by Quoting

The true distinctions emerge when parameters are quoted. Consider arguments containing spaces:

set -- "arg  1" "arg  2" "arg  3"

Comparison of Unquoted Expansion

When used without quotes, both undergo word splitting:

for word in $*; do echo "$word"; done
# Output:
# arg
# 1
# arg
# 2
# arg
# 3

for word in $@; do echo "$word"; done  
# Output:
# arg
# 1
# arg
# 2
# arg
# 3

Significant Differences in Quoted Expansion

With quoting applied, the differences become apparent:

for word in "$*"; do echo "$word"; done
# Output:
# arg  1 arg  2 arg  3

for word in "$@"; do echo "$word"; done
# Output:
# arg  1
# arg  2
# arg  3

"$*" combines all parameters into a single string, while "$@" maintains each parameter's individuality.

Impact of the IFS Variable

The behavior of $* is influenced by the IFS (Internal Field Separator) variable. When using "$*", parameters are joined using the first character of IFS:

IFS=:
echo "$*"
# Output: arg  1:arg  2:arg  3

Practical Application Scenarios

Best Practices for Argument Passing

When needing to pass arguments verbatim to other commands, "$@" is typically the correct choice:

wrapper_command() {
    # Correct: preserves argument boundaries
    some_command "$@"
}

wrapper_command "file name with spaces" "another arg"

Suitable Scenarios for String Processing

"$*" is more appropriate when all parameters need to be treated as a single string:

log_message() {
    local message="$*"
    echo "$(date): $message" >> /var/log/myapp.log
}

log_message User login failed for user "john doe"

Common Pitfalls and Solutions

Quoting Nesting Issues

Proper quoting is crucial in complex scripts:

# Incorrect example
for arg in $@; do
    some_command $arg  # Spaces in arguments cause issues

done

# Correct approach
for arg in "$@"; do
    some_command "$arg"  # Maintains argument integrity
done

Default Iteration Behavior

Bash provides a simplified iteration syntax that behaves identically to "$@":

for word; do  # Equivalent to for word in "$@"; do
    echo "$word"
done

Summary and Recommendations

Understanding the differences between $@ and $* is essential for writing robust Bash scripts. Key recommendations include:

By mastering these concepts, developers can create more reliable and maintainable Bash scripts that properly handle various command-line argument scenarios.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.