Parsing command line options makes a Bash script safer to run repeatedly because each input has a named flag instead of relying on positional order alone. A script that accepts ./report-options.sh -n backups -v is easier to read in history, cron entries, and saved runbooks than a script that expects several unnamed arguments.
The getopts builtin reads short options one at a time, stores option arguments in OPTARG, and advances OPTIND so the script can separate parsed flags from remaining file or path arguments. A leading colon in the option string lets the script print its own missing-argument and invalid-option messages.
The example below handles a required -n NAME option, an optional -v flag, and remaining file names. It stays with short options because getopts does not implement GNU-style long options such as --name without additional parsing.
Related: How to create and run a Bash script
Related: How to use a case statement in Bash
Related: How to enable color output in Bash scripts
#!/usr/bin/env bash set -euo pipefail usage() { printf "Usage: %s -n NAME [-v] [FILE...]\n" "${0##*/}" >&2 } verbose=0 name="" while getopts ":n:vh" opt; do case "$opt" in n) name=$OPTARG ;; v) verbose=1 ;; h) usage; exit 0 ;; :) printf "Missing argument for -%s\n" "$OPTARG" >&2; usage; exit 2 ;; \?) printf "Invalid option: -%s\n" "$OPTARG" >&2; usage; exit 2 ;; esac done shift "$((OPTIND - 1))" if [ -z "$name" ]; then printf "Missing required option: -n\n" >&2 usage exit 2 fi printf "name=%s\n" "$name" printf "verbose=%s\n" "$verbose" printf "remaining=%s\n" "$*"
The option string :n:vh means n requires an argument, v and h do not, and the script handles option errors itself.
$ bash -n report-options.sh
No output means Bash did not find a syntax error while parsing the script.
$ bash report-options.sh -v -n backups archive.log access.log name=backups verbose=1 remaining=archive.log access.log
The shift "$((OPTIND - 1))" line removes parsed options so $* contains only the remaining non-option arguments.
$ bash report-options.sh -n Missing argument for -n Usage: report-options.sh -n NAME [-v] [FILE...]
$ bash report-options.sh -v Missing required option: -n Usage: report-options.sh -n NAME [-v] [FILE...] $ printf 'exit=%s\n' "$?" exit=2
Run this check in a shell where set -e is not active, or capture the failure with an explicit conditional, because the script is expected to exit with status 2.
$ rm -f report-options.sh