I'm reading the documentation for getopt, but I still don't understand what problem it solves or when I should use it. Could someone explain its purpose with a simple example, and clarify how it relates to Bash's built-in getopts?
3 Answers
They help shell scripts process command-line options such as `-h`, `-v`, or `--output file`. Instead of manually inspecting every item in `$@`, an option parser checks which flags are valid, handles options that require values, and separates options from positional arguments such as filenames. It also supports common conventions like combining short flags (`-abc`), using long options, and treating everything after `--` as a regular argument. For a simple script that only needs a couple of positional arguments, using `$1`, `$2`, and so on may be clearer. The parser becomes useful when your script has several flags or options with arguments.
For most Bash scripts, start with the built-in `getopts`. A typical pattern is `while getopts "hvo:" opt; do case "$opt" in h) ... ;; v) ... ;; o) output="$OPTARG" ;; esac; done`. The letters in the option string define the accepted short options, and a colon means that option requires a value. It handles cases like `-v`, `-o result.txt`, and grouped flags such as `-hv`. It is portable, but it does not directly support GNU-style long options like `--verbose`.
The external `getopt` command is a separate tool that preprocesses the argument list. It can validate and reorder options, support long options, and deal with more elaborate command-line syntax. Afterward, a script commonly uses `set --` and a `case` loop to process the normalized arguments. Be cautious with examples that use `eval`, though: quoting must be handled exactly right, or arguments containing spaces or special characters can be interpreted incorrectly. Also, implementations differ between systems, so scripts that need to run on different Unix platforms should consider portability before relying on extended features.
The `--` separator is especially useful when a filename begins with a dash. For example, `command -- -notes.txt` tells the command to treat `-notes.txt` as a filename rather than another option.

That clears it up. My current scripts are simple enough that positional parameters will probably do, but now I understand why tutorials introduce option parsing.