Looking between your question and the comments on Adityaβs answer, I would recommend the following:
[getopts]$ cat go #!/bin/bash function print_help { echo "Usage" >&2 ; } while getopts vtrsc name; do case $name in v) VALIDATE=1;; t) TEST=1;; r) REPORT=1;; s) SYNC=1;; c) CLEAR=1;; ?) print_help; exit 2;; esac done echo "OPTIND: $OPTIND" echo ${#@} shift $((OPTIND - 1)) while (( "$#" )); do if [[ $1 == -* ]] ; then echo "All opts up front, please." >&2 ; print_help ; exit 2 fi echo $1 shift done
Since each of them is a logical flag option, you don't need (and really don't need) the arguments, so we get rid of the colons. None of these characters are in IFS, so we donβt need to wrap this in quotation marks, this will be one token for getopts anyway.
Then we change \? on one ? and get rid of * , since * will match before the literal \? , and we could also combine the rules into a single default match. This is good, since any option specified with the - prefix should be an option, and users will expect the program to fail if they specify an option that you do not expect.
getopts will parse until the first, which is not an argument, and set OPTIND to this position value. In this case, we will move OPTIND - 1 (since opts 0-indexed) from the front. Then we will skip these arguments by canceling them, repeating them or failing if they start with - .
And check:
[getopts]$ ./go OPTIND: 1 0 [getopts]$ ./go -t -v go go OPTIND: 3 4 go go [getopts]$ ./go -d -v go go ./go: illegal option -- d Usage [getopts]$ ./go -t go -v go -d OPTIND: 2 5 go All opts up front, please. Usage
source share