How to parse command line arguments in Bash

Categories:

Overview

getoptsgetopt
Implementationbuiltin (POSIX)util-linux package
Short options✅︎✅︎
Long options✅︎
Parsingone by oneall at once
Quiet modeOPTERR=0-q | --quiet

getopts

getopts — Bash builtin command.

Example

 1parse_args() {
 2  local OPT OPTARG
 3  local -i OPTIND=1 OPTERR=0
 4  # shellcheck disable=SC2220
 5  while getopts ':a:bvVh' OPT; do
 6    case $OPT in
 7      a) arg1="$OPTARG" ;;
 8      b) arg2=1 ;;
 9      v) verbose=1 ;;
10      V) show_version; exit 0 ;;
11      h) show_usage; exit 0 ;;
12      :) echo "missing argument for option -$OPTARG" >&2; exit 3 ;;
13      *) echo "invalid option -$OPTARG" >&2; exit 2 ;;
14    esac
15  done; shift $(( OPTIND - 1 ))
16}

Error handling

  • by getopts itself:
    • no setup needed
    • prints error message
    • returns error code ($? != 0)
  • manually (silent mode):
    • setup:
      • set OPTERR=0
      • or add : to the beginning of optstring, e. g. :a:bh
    • OPT == '?' — invalid option
    • OPT == ':' — missing argument

getopt

getopt — parse command options (enhanced), part of the util-linux package.

Example

 1declare -ir VERBOSE_MIN=0 VERBOSE_MAX=3
 2declare -r opt='a:bqvVh'
 3declare -ar long=(
 4  option-a:
 5  option-b
 6  quiet
 7  verbose
 8  version
 9  help
10)
11declare args a
12declare -i b
13args="$(IFS=','; getopt --name="${0##*/}" --opt="$opt" --long="${long[*]}" -- "$@")" || exit "$?"
14eval set -- "$args"
15while true; do
16  case $1 in
17    -a|--option-a) a="$2"; shift ;;
18    -b|--option-b) b=1 ;;
19    -q|--quiet) (( verbose > VERBOSE_MIN )) && (( --verbose )) ;;
20    -v|--verbose) (( verbose < VERBOSE_MAX )) && (( ++verbose )) ;;
21    -V|--version) show_version; exit 0 ;;
22    -h|--help) show_usage; exit 0 ;;
23    --) shift; break ;;
24  esac
25  shift
26done
27# ...