0

I am writing a bash script with getopts which contains multiple case statements. My requirement is to be able to decide when getopts can take multiple options and when not.

while getopts "hla:d:t:k:w:e:f:i:m:u:L:D:" options
do
    case $options in
        h)
            if [[ "${OPTARG}" = -* ]]; then
                echo "Multiple options are not allowed"
                exit 1
            fi
            verboseHelpAndExit
            break
            ;;
        l)
            if [[ "${OPTARG}" = -* ]]; then
                echo "Multiple options are not allowed"
                exit 1
            fi
            if [ "$#" -gt 0 ] || [ "$1" != '-l' ]; then
                echo "No parameters allowed"
            else
                list_users
            fi
            break
            ;;
        w)
            warn="$OPTARG"
            check_for_integer $warn
            ;;
        e)
            expire="$OPTARG"
            check_for_integer $expire
            ;;

here -h and -l should not take any other option and should give error if any other option is passed, but -w and -e can take multiple options, What is wrong with my code block?

Cyrus
  • 84,225
  • 14
  • 89
  • 153
  • It's generally best to check for option conflicts (e.g. `-h` and anything else) *after* parsing all options (i.e. after the `while getopts` loop). – Gordon Davisson Oct 27 '20 at 12:45
  • Any example please. The problem I am seeing is other options don't reflect in `$OPTARG` variable and hence the If block fails. – Rajesh Kumar Oct 27 '20 at 12:51
  • 1
    `Any example please` ? For example here: https://www.shellscript.sh/tips/getopts/ `The problem I am seeing is other options don't reflect in $OPTARG` I do not understand, why do you expect to see anything in OPTARG? From the man page I see, that when an option without an option-argument is found, then OPTARG will be unset. – KamilCuk Oct 27 '20 at 13:09
  • I am just trying serval things. One option was to check for '-' in $OPTARG, which I am doing using the if block. `myscript.sh -h -l` should not work but `myscript -w 12 -e 10` should work. – Rajesh Kumar Oct 27 '20 at 13:18
  • in the optstring you've designated `h` and `l` as not having arguments which means `myscript -h -l` **should** work and a) OPTARG should be unset and b) you do not need/want any tests against OPTARG by your `h` and `l` pattern processing; said pattern processing should just be: `h) verboseHelpAndExit; break;; l) list_users; break;;` ; or do you mean that if `-h` or `-l` are used then the only **legal** invocation is `myscript -h` or `myscript -l` (with no other command line flags/args being allowed)? – markp-fuso Oct 27 '20 at 13:50
  • Right. I do not want `-h` and `-l` to be used together. `myscript.sh -h -l` should give an error something like "Cannot use two parameters together" , while `myscript.sh -w 12 -e 10` should work as it is. There are several other options in the script, so I need a way to control how many options can be passed simultaneously. – Rajesh Kumar Oct 27 '20 at 14:33
  • 1
    The best way to do this is to process all options with the `getopts` loop, setting variables to indicate which ones were passed, and then *after* the loop, check for illegal combinations. See [this example](https://stackoverflow.com/questions/16483119/an-example-of-how-to-use-getopts-in-bash/16496491#16496491), although there it's making sure that either `-s` or `-p` was passed; in your case, you'd have something like `if [[ -n "${h}" && -n "${l}" ]]; then echo "Multiple options are not allowed"` – Gordon Davisson Oct 27 '20 at 21:37
  • Thank you for your revert. I was able to do this as per your suggestions. – Rajesh Kumar Nov 03 '20 at 15:31

0 Answers0