-
-
Save cosimo/3760587 to your computer and use it in GitHub Desktop.
#!/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 |
Thanks for the code. A question, for anyone who can help me: how to edit the code to let the script read another integer value as well?
For example, suppose you want to include the numeric integer -x
parameter (long: --xxx-size
).
The new input line should work for something like: ./parse-options.sh -s 20 -x 100
How can you do that? I tried by duplicating the STACK_SIZE line but it did not work. Thanks!
@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
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.
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?
It doesn't work me also, same problem like @wilderfield explained (MAC OS).
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...
@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.
@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.
I have written a faster version by myself which does not need the external program getopt to parse long options. It is compatible to bash 3,4 and ksh (fastest). Surely there are more compatible shell's but this are the shells I have tested. It is a little bit more advanced than your version but easy to maintain. Click here to see it on gist.github.com