Skip to content

Instantly share code, notes, and snippets.

@cosimo
Created September 21, 2012 09:31
Show Gist options
  • Save cosimo/3760587 to your computer and use it in GitHub Desktop.
Save cosimo/3760587 to your computer and use it in GitHub Desktop.
Example of how to parse options with bash/getopt
#!/bin/bash
#
# Example of how to parse short/long options with 'getopt'
#
OPTS=`getopt -o vhns: --long verbose,dry-run,help,stack-size: -n 'parse-options' -- "$@"`
if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi
echo "$OPTS"
eval set -- "$OPTS"
VERBOSE=false
HELP=false
DRY_RUN=false
STACK_SIZE=0
while true; do
case "$1" in
-v | --verbose ) VERBOSE=true; shift ;;
-h | --help ) HELP=true; shift ;;
-n | --dry-run ) DRY_RUN=true; shift ;;
-s | --stack-size ) STACK_SIZE="$2"; shift; shift ;;
-- ) shift; break ;;
* ) break ;;
esac
done
echo VERBOSE=$VERBOSE
echo HELP=$HELP
echo DRY_RUN=$DRY_RUN
echo STACK_SIZE=$STACK_SIZE
@sw-carlin
Copy link

@davidechicco it took me a while to figure this out because get-opt is cryptic, but the colon at the end of stack-size: in the get-opt command means "requires argument". http://www.bahmanm.com/blogs/command-line-options-how-to-parse-in-bash-using-getopt

@ascherer
Copy link

ascherer commented Jul 21, 2018

The script works just as well with #!/bin/sh aka dash on (K)Ubuntu.

However, due to an incompatible getopt, this script fails on BSD and MacOS.

@wilderfield
Copy link

Hey,
This actually doesn't work for me. While the variable OPTS does get appended with -- , that string does not exist in the actual command line arguments. The while loop never encounters a -- . Am I missing something?

@Kocjan
Copy link

Kocjan commented Jan 8, 2019

It doesn't work me also, same problem like @wilderfield explained (MAC OS).

@aceeric
Copy link

aceeric commented Aug 16, 2019

Question for anyone who knows: I see the asterisk case above and elsewhere. I've not been able to trigger it. Under what circumstances would the script enter that case statement? Thanks...

@seanw2020
Copy link

seanw2020 commented Oct 4, 2019

@aceeric, if you handle each case correctly, that should never happen. For example, if you omit the -s | --stack-size ) STACK_SIZE="$2"; shift; shift ;; line, and then issue parse-options -s, you'll trigger the *) pattern's command.

@wilderfield and @Kocjan, MacOS is more FreeBSD (i.e., Unix) than Linux. If you issue man getopt and man getopts (note the plural spelling), you'll see results for both, but the first line of the output will say BSD and will not mention long options. Neither BSD version allows long options like --help or --foobar. For that, you need to install brew install coreutils. For details, see https://stackoverflow.com/a/47542834/1231693. After that, man getopt will NOT say BSD and will mention long options.

For anyone interested in "test driving" what's really happening in this gist, try the following one-liner:

  getopt -o vhns: --long verbose,dry-run,help,stack-size: -n 'parse-options' -- "$@" <<< bash foo --verbose -s 1 bar

If you vary the number and variety of options at the end, you can see how getopt works.

@severo
Copy link

severo commented May 7, 2020

@davidechicco it took me a while to figure this out because get-opt is cryptic, but the colon at the end of stack-size: in the get-opt command means "requires argument". http://www.bahmanm.com/blogs/command-line-options-how-to-parse-in-bash-using-getopt

Thanks for this!!! I hadn't notice and couldn't make my script work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment