Parsing Short Options with getopts
Bash already provides a parser for conventional short options: `getopts`. It understands option letters and required values without external utilities or re-parsing the command line.
Learning objectives
By the end of this lesson
- Define an optstring.
- Use OPTARG and OPTIND.
- Handle grouped flags.
- Report unknown options and missing values cleanly.
- Shift parsed options before reading operands.
1. getopts parses one option per iteration
verbose=false
environment=staging
while getopts 've:' option; do
case $option in
v) verbose=true ;;
e) environment=$OPTARG ;;
esac
doneIn the optstring ve:, v is a flag and e requires an argument because it is followed by a colon.
2. OPTARG contains the current option argument
output=""
while getopts 'o:' option; do
case $option in
o) output=$OPTARG ;;
esac
done
printf 'output=%s\n' "$output"3. OPTIND tracks parser progress
while getopts 've:' option; do
:
done
shift "$((OPTIND - 1))"
printf 'remaining operands=%d\n' "$#"After the shift, $1 is the first non-option operand remaining for your application.
4. Independent short flags can be grouped
while getopts 'vqn' option; do
case $option in
v) verbose=true ;;
q) quiet=true ;;
n) dry_run=true ;;
esac
done
# Users may write -vqn5. A leading colon gives your script control over errors
while getopts ':ve:' option; do
case $option in
v) verbose=true ;;
e) environment=$OPTARG ;;
:)
printf 'option -%s requires an argument\n' "$OPTARG" >&2
exit 64
;;
\?)
printf 'unknown option: -%s\n' "$OPTARG" >&2
exit 64
;;
esac
doneThis keeps parser diagnostics consistent with the rest of your CLI.
6. getopts validates grammar, not business meaning
case $environment in
dev|staging|prod) ;;
*)
printf 'invalid environment: %s\n' "$environment" >&2
exit 65
;;
esacgetopts can know that -e requires text, but it cannot know which environment names your tool permits.
7. Parse operands after shifting options
shift "$((OPTIND - 1))"
service=${1:-}
[[ -n $service ]] || {
printf 'SERVICE required\n' >&2
exit 64
}8. Reset OPTIND for an independent second parse
parse_options() {
local option
OPTIND=1
while getopts ':v' option; do
case $option in
v) printf 'verbose\n' ;;
esac
done
}
parse_options -v
parse_options -vOPTIND is shell state; reset it when a function performs a new, independent parse in the same process.
9. getopts can parse a function argument vector
parse_deploy_options() {
local option
OPTIND=1
while getopts ':e:v' option "$@"; do
case $option in
e) printf 'environment=%s\n' "$OPTARG" ;;
v) printf 'verbose\n' >&2 ;;
esac
done
}
parse_deploy_options -v -e prod10. getopts is not a general GNU long-option parser
Native Bash getopts targets short options such as -v and -e prod. If you need --environment=prod, use a deliberate manual parser or a stronger CLI framework.
External getopt implementations differ across systems, so do not assume GNU-specific behavior everywhere.
11. Hands-on lab: short-option deployment CLI
mkdir -p "$HOME/devops-academy/bash/chapter06/lesson03"
cd "$HOME/devops-academy/bash/chapter06/lesson03"
cat > deploy-short.sh <<'EOF'
#!/usr/bin/env bash
verbose=false
dry_run=false
environment=staging
replicas=2
while getopts ':vne:r:' option; do
case $option in
v) verbose=true ;;
n) dry_run=true ;;
e) environment=$OPTARG ;;
r) replicas=$OPTARG ;;
:) printf 'option -%s requires a value\n' "$OPTARG" >&2; exit 64 ;;
\?) printf 'unknown option: -%s\n' "$OPTARG" >&2; exit 64 ;;
esac
done
shift "$((OPTIND - 1))"
service=${1:-}
[[ -n $service ]] || { printf 'SERVICE required\n' >&2; exit 64; }
case $environment in dev|staging|prod) ;; *) exit 65 ;; esac
[[ $replicas =~ ^[0-9]+$ ]] && (( 10#$replicas >= 1 )) || exit 66
printf 'PLAN service=%s env=%s replicas=%d verbose=%s dry_run=%s\n' \
"$service" "$environment" "$((10#$replicas))" "$verbose" "$dry_run"
EOF
bash deploy-short.sh -vn -e prod -r 3 api
bash deploy-short.sh -e staging worker
bash deploy-short.sh -x api || true
bash deploy-short.sh -e || trueVerification checklist
12. Knowledge check
Question 1. What does a colon after an option letter mean?
Question 2. What does OPTARG contain?
Question 3. Why shift by OPTIND - 1?
Question 4. Does Bash getopts provide a general long-option parser?
13. Summary
getopts is Bash's built-in short-option parser. Use the optstring to define flags and required values, OPTARG for option data, and OPTIND to locate remaining operands. Your script still owns semantic validation.
14. Further reading
- GNU Bash Reference Manual —
getopts. - POSIX
getoptsutility specification. - POSIX Utility Syntax Guidelines.
- ShellCheck documentation — option parsing.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this address.