The easiest way to parse arguments using getoptions for bash and shell scripts
Tags: bash, shellscript, devops, showdev
Published: 2021-04-30 00:20:39

A lot of people have been looking for a best practice to use `getopt` and `getopts` for long years. A [number of methods](https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash/14203146) to parse arguments were thought up, but no perfect solution was found. However, with the advent of the [getoptions](https://github.com/ko1nksm/getoptions), that long journey comes to an end.

## The getoptions

It is designed to be a ready-to-use replacement for `getopt` and `getopts`. No special embedded comments, configuration files, or pre-build is required, so the learning curve is low and maintenance is easy. In other words, just install a [getoptions](https://github.com/ko1nksm/getoptions/releases) and the following shell script will work like a charm.

```sh
#!/bin/sh

VERSION="0.1"

parser_definition() {
  setup   REST help:usage -- "Usage: example.sh [options]... [arguments]..." ''
  msg -- 'Options:'
  flag    FLAG    -f --flag                 -- "takes no arguments"
  param   PARAM   -p --param                -- "takes one argument"
  option  OPTION  -o --option on:"default"  -- "takes one optional argument"
  disp    :usage  -h --help
  disp    VERSION    --version
}

eval "$(getoptions parser_definition) exit 1" # argument parsing

echo "FLAG: $FLAG, PARAM: $PARAM, OPTION: $OPTION"
printf '%s\n' "$@" # output rest arguments
```

```console
$ ./example.sh -h
Usage: example.sh [options]... [arguments]...

Options:
  -f, --flag                  takes no arguments
  -p, --param PARAM           takes one argument
  -o, --option[=OPTION]       takes one optional argument
  -h, --help
      --version
```

## It is an option parser generator

The `getoptions` is essentially a generator that generates an option parser, but claims to be an option parser. Because it is very fast (minimum <= 10ms), can dynamically generate an option parser at runtime and parse arguments.

## I don't want to install the getoptions!

If you want to run your script without `getoptions` installed, you can include its core library in your script and distribute it. The license is [CC0](https://creativecommons.org/publicdomain/zero/1.0/), so there are no restrictions at all. Its size is 200-300 lines (5KB-8KB), depending on the configuration, is extremely compact compared to other implementations.

## I don't want to include the library!

If you do not want to include the library in your scripts, you can use it as an option parser generator. If you generate the parser beforehand, you don't need to include the library, and execution speed will be even faster. The generated parser is simple, short, and only one function. Its size will be about the same as what you would write by hand.

## No requirements and POSIX-compliant

All you need to use `getoptions` is only POSIX shell (i.e. dash 0.5.4+, bash 2.03+, ksh88+, zsh 3.1.9+). It is strongly standards-aware and supports both POSIX and GNU option syntax and supports long options as well as long option abbreviations and subcommands.

## Conclusion

The `getoptions` is very easy to use. But in contrast to its small size, is has a lot of features, extensibility and flexibility. You can customize error messages, validations, automatically generate help, and call functions when specified options.

If you want to know more about the advanced features, please visit the project site. There are a variety of examples available. However, for basic usage, there is nothing more to explain.