getopts is a built-in Unix shell command for parsing command-line arguments. It is designed to process command line arguments that follow the POSIX Utility Syntax Guidelines, based on the C interface of getopt. The predecessor to was the external program by Unix System Laboratories.
History
The original had several problems: it could not handle whitespace or shell metacharacters in arguments, and there was no ability to disable the output of error messages. getopts was first introduced in 1986 in the Bourne shell shipped with Unix SVR3. It uses the shell's own variables to track the position of current and argument positions, and, and returns the option name in a shell variable. Earlier versions of the Bourne shell did not have getopts. In 1995, getopts was included in the Single UNIX Specificationversion 1 / X/Open Portability Guidelines Issue 4. As a result, getopts is now available in shells including the Bourne shell, Korn shell, Almquist shell, Bash and Zsh. The modern usage of was partially revived mainly due to an enhanced implementation in util-linux. This version, based on the BSD, not only fixed the two complaints around the old, but also introduced the capability for parsing GNU-style long options and optional arguments for options, features that lacks. The various BSD distributions, however, stuck to the old implementation.
Usage
The usage synopsis of getopt and getopts is similar to its C sibling: getopt optstring' getopts optstringvarname'
The optstring part has the same format as the C sibling.
The parameters part simply accepts whatever one wants getopt to parse. A common value is all the parameters, in POSIX shell.
* This value exists in getopts but is rarely used, since it can just access the shell's parameters. It is useful with resetting the parser, however.
The varname part of getopts names a shell variable to store the option parsed into.
The way one uses the commands however varies a lot:
getopt simply returns a flat string containing whitespace-separated tokens representing the "normalized" argument. One then uses a while-loop to parse it naively.
getopts is meant to be repeatedly called like the C getopt. When it hits the end of arguments, it returns 1.
Enhancements
In various getopts
In spring 2004, the libc implementation for was enhanced to support long options. As a result, this new feature was also available in the built-in commandgetopts of the Bourne Shell. This is triggered by parenthesized suffixes in the optstring specifying legal options. Korn shell and Zsh both have an extension for long arguments. The former is defined as in Solaris, while the latter is implemented via a separate command. Korn shell additionally implement optstring extensions for options beginning with instead of.
In Linux getopt
An alternative to getopts is the Linux enhanced version of getopt, the external command line program. The Linux enhanced version of getopt has the extra safety of getopts plus more advanced features. It supports long option names and the options do not have to appear before all the operands. It also supports escaping metacharacters for shells and optional arguments.
Comparison
Examples
Suppose we are building a Wikipedia downloader in bash that takes three options and zero extra arguments: wpdown -a article name -l -v When possible, we allow the following long arguments: -a --article -l --language, --lang -v --verbose For clarity, no help text is included, and we assume there is a program that downloads any webpage. In addition, all programs are of the form:
!/bin/bash
VERBOSE=0 ARTICLE='' LANG=en
if ); then printf '%s\n' 'Non-option arguments:' printf '%q ' "$" fi if ); then printf 'Downloading %s:%s\n' "$LANG" "$ARTICLE" fi if ! $ARTICLE ; then printf '%s\n' "No articles!">&2 exit 1 fi save_webpage "https://$.wikipedia.org/wiki/$"
Using old getopt
The old getopt does not support optional arguments:
parse everything; if it fails we bail
args=`getopt 'a:l:v' $*` || exit
now we have the sanitized args... replace the original with it
set -- $args while true; do case $1 in ); shift;; ARTICLE=$2; shift 2;; LANG=$2; shift 2;; shift; break;; exit 1;; # error esac done remaining=
This script will also break with any article title with a space or a shell metacharacter in it.
Using getopts
Getopts give the script the look and feel of the C interface, although in POSIX optional arguments are still absent:
!/bin/sh
while getopts ':a:l:v' opt; do case $opt in );; ARTICLE=$OPTARG;; LANG=$OPTARG;; # "optional arguments" case $OPTARG in exit 1;; # error, according to our syntax :;; # acceptable but does nothing esac;; esac done shift "$OPTIND"
remaining is "$@"
Since we are no longer operating on shell options directly, we no longer need to shift them. However, a slicing operating is required to get the remaining arguments now.
Using Linux getopt
Linux getopt escapes its output and an "eval" command is needed to have the shell interpret it. The rest is unchanged:
We use "$@" instead of $* to preserve argument-boundary information
ARGS=$ || exit eval "set -- $ARGS" while true; do case $1 in
); shift;;
ARTICLE=$2; shift 2;;
# handle optional: getopt normalizes it into an empty string if ; then LANG=$2; shift; fi shift;; shift; break;; exit 1;; # error esac done remaining=