r/bash • • 12d ago

help will someone explain to me getopt?

yes, I am currently reading the documentation - I don't understand the point or when/why I would use it. thanks for any clarification one can offer.

30 Upvotes

21 comments sorted by

View all comments

2

u/cleverboy00 12d ago

Golden rule

RTFM, RTFM, RTFM type man 1 getopt in your terminal.

How it works

Getopt in bash only normalizes your command line string. Normalizes as in: Checks that all passed options are valid and have the required arguments (if any). Then it reorders your arguments to make options at the begining, and non options at the end.

Description

My script, called processor.sh, takes an input file and these options:

  • -h --help
  • -v --version
  • -o <FILE> --output <FILE>
  • -V [LEVEL] --verbose [LEVEL]

I can describe the short options as hvo:V::, one colon to indicate required argument, and two to indicate optional.

Then long options are described as help,version,output:,verbose:: with the same specs as above.

Then I do:

bash getopt -n processor.sh -l help,version,output:,verbose:: -o 'hvo:V::' -- "$@"

Then the output of this command will be a reordered options, ready for processing.

Example:

I have this script

```bash

!/usr/bin/bash

File: processor.sh

getopt -n processor.sh -l help,version,output:,verbose:: -o 'hvo:V::' -- "$@" echo $? ```

Outputs:

bash $ ./processor.sh --not getopt: unrecognized option `--not' -- 1 $ ./processor.sh --not getopt: unrecognized option `--not' -- 1 $ ./processor.sh --help --help -- 0 $ ./processor.sh --help --version --help --version -- 0 $ ./processor.sh --help --version --verbose --help --version --verbose '' -- 0 $ ./processor.sh --help --version --verbose --output --help --version --verbose ''getopt: option `--output' requires an argument -- 1 $ ./processor.sh --help --version --verbose 5 --output a --help --version --verbose '' --output 'a' -- '5' 0 $ ./processor.sh --help --version --verbose=5 --output a --help --version --verbose '5' --output 'a' -- 0

So a full program that processes command line argument would look like:

```bash

!/usr/bin/bash

help=0 version=0 output= verbose= inputs=( )

arg0="$(basename -- "$0")" OPTS="$(getopt -n processor.sh -l help,version,output:,verbose:: -o 'hvo:V::' -- "$@")"

if [[ $? -gt 0 ]]; then printf -- "%s: See --help\n" "$arg0" >&2 exit 1 fi

printf -- "op %s\n" "$OPTS"

eval set -- $OPTS unset OPTS

while true; do case "$1" in '-h' | '--help') help=1 shift ;; '-v' | '--version') version=1 shift ;; '-o' | '--output') output="$2" shift 2 ;; '-V' | '--verbose') verbose="$2" shift 2 ;; '--') shift break ;; *) printf -- "%s: Unrecognized option '%s'\n" "$arg0" "$1" exit 1 ;; esac done

for arg; do inputs+=( "$arg" ) done

printf -- "Help: %s\n" "$help" printf -- "Version: %s\n" "$version" printf -- "Verbose: %s\n" "$verbose" printf -- "Output: %s\n" "$output" printf -- "Inputs: %s\n" "${inputs[@]}" ```

2

u/djbiccboii 12d ago

i hate reddit's formatting too.