0

I'm trying to see whether I can use getopts for my Bash script. However, I'm not sure what's wrong:

#! /bin/bash

while getopts "a:b" opt ; do
    case $opt in
        a)
            A_OPTION="option a was given argument $OPTARG"
            ;;
        b)
            B_OPTION="option b was found"
            ;;
    esac
done
if [ -n "$A_OPTION" ] ; then echo $A_OPTION ; fi
if [ -n "$B_OPTION" ] ; then echo $B_OPTION ; fi
shift $((OPTIND - 1))
echo "The remaining arguments are: $@"

The output is:

$ ./getopts-test foo goo -a moo -b
The remaining arguments are: foo goo -a moo -b
$ ./getopts-test -a moo -b foo goo
option a was given argument moo
option b was found
The remaining arguments are: foo goo
$ ./getopts-test -a moo foo goo -b
option a was given argument moo
The remaining arguments are: foo goo -b
$ ./getopts-test -b foo goo -a moo
option b was found
The remaining arguments are: foo goo -a moo

Why doesn't the script detect the options in all the cases? Is getopts only useful when the options are all provided upfront and not mixed with other arguments?

1

(this is too long to be a comment and too poor to be an answer)

getopt try to detect single letter option with - (minus sign), and option with argument.

It stop when there is no (no more) option (no -b, no -a foo). It doesn't parse the full list.

So answer to second question is yes.

You might whish to write a getopt parser yourself and deal with this question are -foo --bar arguements (e.g. a file, a string) or an option.

for a long time tradition was to put options first, argument later, precisely so you knew when option stop, and if -foo was an actual filename.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.