Friday, July 17, 2009

Bash: Iterating Over Command-Line Arguments

Shell script parameters are available through the positional variables $1, $2, $3, etc. They are also placed in the "special" variables $* and $@. The following script illustrates how those values are expanded.

#!/bin/bash

print_arguments () {
idx=1
for arg; do
echo " param $idx: $arg"
let idx++
done
echo
}

echo "\$* - arguments with spaces are split"
print_arguments $*

echo "\$@ - same"
print_arguments $@

echo "\"\$*\" - expands to single value"
print_arguments "$*"

echo "\"\$@\" - preserves arguments exactly as passed"
print_arguments "$@"

Example output:

$ ./test-param-expansion orange 9 "Bringing Up Baby"
$* - arguments with spaces are split
param 1: orange
param 2: 9
param 3: Bringing
param 4: Up
param 5: Baby

$@ - same
param 1: orange
param 2: 9
param 3: Bringing
param 4: Up
param 5: Baby

"$*" - expands to single value
param 1: orange 9 Bringing Up Baby

"$@" - preserves arguments exactly as passed
param 1: orange
param 2: 9
param 3: Bringing Up Baby

So to preserve the command-line arguments exactly as supplied, use the special variable "$@" when iterating. Mnemonic: quote at the right place.

Example for loops:

#!/bin/sh

# loop over all args
for arg in "$@"; do
echo $arg
done

# short-cut; same as above
for arg; do
echo $arg
done

See also: Bash Manual: Special Parameters

No comments: