Skip to content

Positional Parameters

Positional parameters are the arguments passed to a Bash script, accessible via variables like $1, $2, etc. When scripts need to process multiple arguments dynamically, understanding $@, $*, and shift is critical for robust argument manipulation. These constructs allow scripts to handle variable numbers of inputs, iterate over arguments, or reposition parameters for further processing.


$@ vs $*: Expanding Arguments

Bash provides two special variables for accessing all positional arguments: $@ and $*. While both represent the list of arguments, their expansion behavior differs.

$@ (Array-like Expansion)

  • Treats each argument as a separate string, preserving word boundaries.
  • Ideal for iterating over arguments or passing them to subcommands.
  • Example:
    #!/bin/bash
    for arg in "$@"; do
      echo "Argument: $arg"
    done
    
    If the script is called as ./script.sh "hello world", the loop will process "hello world" as a single argument.

$* (Single String Expansion)

  • Treats all arguments as one concatenated string, separated by the first character of IFS (typically whitespace).
  • Useful for passing arguments to commands that expect a single string.
  • Example:
    #!/bin/bash
    echo "All arguments: $*"
    
    Calling ./script.sh arg1 arg2 outputs: All arguments: arg1 arg2.

Key Difference: $@ preserves argument boundaries, while $* merges them. Use $@ for safety when iterating or passing arguments to subcommands.


shift: Repositioning Positional Parameters

The shift command removes arguments from the positional parameter list, effectively "shifting" them. This is useful for processing arguments sequentially or skipping initial parameters.

Basic Usage

  • shift removes the first argument ($1), making $2 the new $1.
  • shift N removes the first N arguments.

Example:

#!/bin/bash
echo "Original args: $*"
shift 2
echo "After shifting 2 args: $*"
Calling ./script.sh a b c d outputs:
Original args: a b c d
After shifting 2 args: c d

Iterative Processing

Combine shift with loops to process arguments step by step:

#!/bin/bash
while [ $# -gt 0 ]; do
  echo "Processing: $1"
  shift
done
This script processes each argument in turn, regardless of how many are provided.


Best Practices

  • Prefer $@ for iterating over arguments or passing them to subcommands to avoid unintended word splitting.
  • Use shift to dynamically adjust the positional parameter list, especially for command-line tools that require sequential argument processing.
  • Avoid relying on $* in scripts where argument boundaries matter, as it can lead to unexpected behavior with spaces or special characters.

Key takeaways

  • $@ expands arguments as separate strings; $* merges them into one.
  • shift modifies the positional parameter list, allowing scripts to process arguments sequentially.
  • Use $@ for robust argument iteration and shift for dynamic repositioning.
  • Always test scripts with edge cases (e.g., empty arguments, spaces) to ensure correct handling.