There are lots of ways of gathering arguments. You can name their position, e.g. $1
is the first argument and $14
is the fourteenth.
You can refer to the argument list like $@
(this preserves spacing) or like $*
(this collapses spacing):
test_args() {
echo '# as "$@"'
for argument in "$@"; do
echo "$argument"
done
echo '# as "$*"'
for argument in "$*"; do
echo "$argument"
done
echo '# as $*'
for argument in $*; do
echo "$argument"
done
}
$ test_args "1 2" three four
# as "$@"
1 2
three
four
# as "$*"
1 2 three four
# as $*
1
2
three
four
Since you're exclusively using long options separated from their arguments by spaces,
while [ "$#" -gt 0 ]; do
case "$1" in
( --network ) NETWORK="$2"; shift ;;
( --network=?* ) NETWORK="${1#*=}" ;;
( --instance_name ) INSTANCE_NAME="$2"; shift ;;
( --instance_name=?* ) INSTANCE_NAME="${1#*=}" ;;
( -* ) echo "Illegal option -- $1" >&2; exit 2 ;;
( * ) break ;; # perhaps non-options are used later
esac
shift
done
This loops on each option and parses it. There are two conditions for each option, which lets us handle when the arguments are spaced from the options (--network bobnet
) or when they're assigned to the options (--network=bobnet
). Spaced means we need to refer to the next argument (thus the extra shift
) while assigned means we need to use parameter subsitution to remove the characters at the front of the string up until (and including) the first =
.
The final shift
pulls the first item off of the argument list so we can operate on the next one. Shifting separately for the two-argument clauses (rather than ending with shift 2
) also allows for binary options like --verbose
, which doesn't contain an argument.
You can also use a while getopts
loop to support a mix of short and long arguments; see my more detailed post on getopts.