Bash Argument Parsing with Getopts
Argument parsing is reading the options a user types after a script name. Getopts reads them one by one in a loop.
Getopts reads flags and values in a loop
The loop reads -v as a flag and -n with its value. The script then prints both results.
verbose=0
name="default"
while getopts "vn:" opt; do
case "$opt" in
v) verbose=1 ;;
n) name="$OPTARG" ;;
esac
done
echo "verbose: $verbose"
echo "name: $name"OPTIND leaves the plain arguments behind
After the loop, shifting by OPTIND minus one drops the options. The plain file names remain and print in order.
verbose=0
while getopts "v" opt; do
case "$opt" in
v) verbose=1 ;;
esac
done
shift $((OPTIND - 1))
echo "verbose: $verbose"
echo "files: $@"A missing value prints a clear error
The -n option needs a value, but none follows it. Getopts prints its error, then the script prints usage and exits.
name="default"
while getopts "vn:" opt; do
case "$opt" in
v) echo "verbose on" ;;
n) name="$OPTARG" ;;
\?) echo "Usage: $0 [-v] -n name" >&2; exit 1 ;;
esac
done
echo "name: $name"An unknown option prints a clear error
The letter z is not in the option string. Getopts prints its error, then the script prints usage and exits.
name="default"
while getopts "vn:" opt; do
case "$opt" in
v) echo "verbose on" ;;
n) name="$OPTARG" ;;
\?) echo "Usage: $0 [-v] -n name" >&2; exit 1 ;;
esac
done
echo "name: $name"Example
#!/bin/bash
verbose=0
name="default"
while getopts "vn:" opt; do
case "$opt" in
v) verbose=1 ;;
n) name="$OPTARG" ;;
\?) echo "Usage: $0 [-v] -n name files" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
echo "verbose: $verbose"
echo "name: $name"
echo "files: $@"Key points
- getopts: a built-in command that reads short options in a loop.
- OPTARG: the value attached to the option just read.
- OPTIND: the position of the next argument still to read.
- shift with OPTIND: a step that drops the options, leaving plain arguments.
- Missing value: an option that needs a value but gets none.
- Unknown option: a letter the script does not accept.
In this example, the loop reads the options first. The -v flag sets verbose, and -n stores its value in name. Shifting by OPTIND minus one drops the options. The script then prints the flag, the name, and the plain file names.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
After getopts finishes, what does OPTIND tell the script?