Parse command-line options without getopts
Bash
#!/usr/bin/env bash
# Parse short and long options with a plain while/case loop.
set -euo pipefail
verbose=false
output=""
files=()
usage() {
printf 'usage: %s [-v] [-o FILE] [path...]\n' "${0##*/}" >&2
exit 64
}
while (($# > 0)); do
case "$1" in
-v|--verbose) verbose=true; shift ;;
-o|--output) output="${2:?missing value for $1}"; shift 2 ;;
-h|--help) usage ;;
--) shift; files+=("$@"); break ;;
-*) printf 'unknown option: %s\n' "$1" >&2; usage ;;
*) files+=("$1"); shift ;;
esac
done
((${#files[@]} > 0)) || usage
if [[ $verbose == true ]]; then
printf 'verbose=on output=%s paths=%d\n' "${output:-stdout}" "${#files[@]}"
fi