I'm reading the Bash documentation for getopt and getopts, but I still don't understand their purpose. What problem do they solve, and when would I use them instead of processing "$@" directly?
4 Answers
Be careful not to treat `getopt` and `getopts` as exactly the same thing. `getopts` is the Bash/POSIX builtin and is generally the portable choice for short options. The external `getopt` command can rearrange arguments and, on some systems, support GNU-style long options and optional arguments, but its behavior differs between GNU/Linux and BSD/macOS. For simple scripts, a small manual parsing loop may be clearer and more portable than either one.
The basic `getopts` pattern looks like `while getopts "hvo:" opt; do case "$opt" in h) ... ;; v) ... ;; o) output="$OPTARG" ;; esac; done`. The colon after `o` means that option requires a value. After parsing, `OPTIND` indicates where the remaining positional arguments begin. This saves you from rewriting all the validation and shifting logic yourself.
For example, a script might accept `-h` for help, `-o FILE` for an output file, and then one or more input files. `getopts` lets you loop over those options with a `case` statement instead of manually inspecting every element of `$@`. It’s useful when your script has several flags or options, but probably unnecessary if it only needs something simple like `$1` and `$2`.
They help scripts process command-line options such as `-h`, `-v`, `-o output.txt`, or longer forms like `--help`. The parser checks whether options are valid, identifies which ones require arguments, supports grouped short options such as `-abc`, and separates options from positional arguments like filenames. It also handles `--`, which tells the script that everything afterward should be treated as a normal argument, even if it begins with a dash.

That clears it up. Most of the examples I found used option parsing without explaining why, and my scripts currently only need a couple of positional arguments.