getopts

getopts is a built-in bash feature. Comparatively, getopt is a separate binary.

getopts Syntax

getopts optstring name [args]

Setting options

Use the optstring variable to set what arguments can be accepted by the program. getopts uses short argument names only (-a, not –arg).

Here's a sample that accepts -a, -b and -c as optional arguments. Getopts does not support required arguments.

Strings for passed arguments must occur after a whitespace.

getopts abc opts

To set an argument as required, add a colon to the end of the argument:

getopts ab:c

Invalid Options

If an invalid option is passed, getopts will throw an error by default:

sample.sh -d
sample.sh: illegal option -- d

When an invalid option is passed, the name variable is set to ?, allowing you to manage the user input. However, bash will still dump its own error as well.

case ?)
  echo "Invalid argument";;

There are two ways to silence errors from bash. One is to set OPTERR variable to zero, and the other is to add a : to the front of the options variable, before any letters.

Valid syntax for both:

OPTERR=0
opts=:abc

Best practice would be to silence the errors using :abc syntax. This allows the invalid option passed to be set as OPTARG, so that the script can see what option the user passed.

case ?)
  echo "Invalid option: -$OPTARG";;

Option Arguments

Arguments following options must have a whitespace between them.

To toggle an option as requiring an argument, add a : to the letter in the options variable.

Require -c option to have an argument, when used.

getopts abc: opt

The argument passed to the option is set as OPTARG.

c)
  echo "Passed -c $OPTARG"

Multiple Arguments

There are two ways to pass multiple arguments to an option: enclose the argument in quotes, or pass the option more than once and build on the old variable.

Quoted argument

bkup.mysql -d "mysql client"
...
d)
  DBS=$OPTARG

Multiple options

bkup.mysql -d mysql -d client
...
d)
  DBS="$DBS $OPTARG"

Missing Argument

If error reporting is silenced using : and an option is passed with an argument, the name variable is set to : and the script can do specific actions based on that input as well.

bkup.mysql -d 
...
getopts abcd:
...
:)
  echo "Option -$OPTARG passed, missing an argument";;

Example

#!/bin/bash
 
while getopts ":a:" opt; do
  case $opt in
    a)
      echo "-a was triggered, Parameter: $OPTARG" >&2
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument." >&2
      exit 1
      ;;
  esac
done