How to handle default values with script arguments/parameters?
How to handle optional arguments with and without right-hand values?
I have several bash scripts depending on optional arguments. I want to minimize my typing and error sources.
There are three cases that I want to handle:
- 1) Parameter is not present: the global default value has to be taken
- 2a) Parameter is present, but no right-hand value is given (-x or -x=): the parameter default value has to be taken
- 2b) Parameter is present, but only an equal sign is given without value (-X=): the empty string should be set
- 3) Parameter is present with given value (-x=Y): the value has to be taken
The following script implements this behavior and serves as a demo. This small script is also published on GitHub Gist as args.sh.
#!/bin/bash
# Bash optional arguments demo
# Three cases are supported:
# 1) Parameter is not present: the global default value is taken
# 2a) Parameter is present, but no right-hand value is given (-x or -x=): the parameter default value is taken
# 2b) Parameter is present, but only an equal sign is given without value (-X=): the empty string is set
# 3) Parameter is present with given value (-x=Y): the value is taken
# 4) Left over parameters are output in verbose mode (-v)
# ./args.sh
# x='X'
# ./args.sh -x
# x='Y'
# ./args.sh -x=Z
# x='Z'
# ./args.sh -x=
# x='Y'
# ./args.sh -X=
# x='X'
# ./args.sh --demox
# x='Y'
# ./args.sh --demox=Z
# x='Z'
# ./args.sh -x -v
# x='Y'
# Remaining arguments: ''
# ./args.sh -x -v -a -b c abc
# x='Y'
# Remaining arguments: '-a -b c abc'
x='X'
verbose=false
POSITIONAL=()
while test $# -gt 0; do
case $1 in
-h|--help)
echo "Args demo: prints value of argument x"
echo
echo "$0 [options]"
echo
echo "Options:"
echo "-x[=VAL], --demox[=VAL] Demo argument, default 'X' if parameter not present, default 'Y' if -x is given without right-hand value"
echo "-X[=VAL], --demoX[=VAL] Demo argument, default 'X' if parameter not present, default 'Y' if -X is given without right-hand value (treating -X= as empty value)"
echo "-v, --verbose Verbose mode: show remaining arguments"
echo "-h, --help Show this help"
echo
exit
;;
-x|--demox|-X|--demoX)
x="Y"
shift
;;
-x=*|--demox=*)
x="${1#*=}"
if [[ $x == "" ]]; then
x="Y"
fi
shift
;;
-X=*|--demoX=*)
x="${1#*=}"
shift
;;
-v|--verbose)
verbose=true
shift
;;
*)
POSITIONAL+=("$1") # save it in an array for later
shift
;;
esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters
echo "x='$x'"
if $verbose; then
echo "Remaining arguments: '$@'"
fi