Getopts help help if cmd is missing. string argument was matched

I am trying to use getopts in bash to parse command line arguments, but I could not figure out how to implement the default action if no arguments were matched (or cmdline was not specified).

This is a very simplified version of what I have tried so far:

while getopts v:t:r:s:c: name; do case $name in v) VALIDATE=1;; t) TEST=1;; r) REPORT=1;; s) SYNC=1;; c) CLEAR=1;; *) print_help; exit 2;; \?) print_help; exit 2;; esac done 

Is there a (simple) way to get it to call print_help; output 2; at the wrong entrance?

+4
source share
4 answers

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 
+3
source

Try the following workaround:

 # Parse the arguments. while getopts ':h?f:' opts; do case ${opts} in f) # Foo argument. ;; # My other arguments. \? | h | *) # Prints help. grep " .)\ #" $0 exit 0 ;; esac done 

So basically -? / -h will print options with comments based on its own source. Assignment : before the parameters print help for any other unknown argument.

+2
source

v:t:r:s:c: must be in double quotes

  "v:t:r:s:c:" 

Based on the script you posted, you probably don't need all these colons :

Also you do not need *)

+1
source

Do you need to specify a leading colon in the getopts options line if you want to enable it ? to match an invalid option - :vtrsc . Also don't you need a backslash before ?

+1
source

Source: https://habr.com/ru/post/1402641/


All Articles