Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional option argument with getopts

while getopts "hd:R:" arg; do   case $arg in     h)       echo "usage"        ;;     d)       dir=$OPTARG       ;;     R)       if [[ $OPTARG =~ ^[0-9]+$ ]];then         level=$OPTARG       else         level=1       fi       ;;     \?)       echo "WRONG" >&2       ;;   esac done 
  • level refers to the parameter of -R, dir refers to parameters of -d

  • when I input ./count.sh -R 1 -d test/ it works correctly

  • when I input ./count.sh -d test/ -R 1 it works correctly

  • but I want to have it work when I input ./count.sh -d test/ -R or ./count.sh -R -d test/

This means that I want -R to have a default value and for the sequence of commands to be more flexible.

like image 959
iverson Avatar asked Jul 17 '12 06:07

iverson


People also ask

What is getopts in shell script?

Description. The getopts command is a Korn/POSIX Shell built-in command that retrieves options and option-arguments from a list of parameters. An option begins with a + (plus sign) or a - (minus sign) followed by a character. An option that does not begin with either a + or a - ends the OptionString.

Should I use getopt or getopts?

The main differences between getopts and getopt are as follows: getopt does not handle empty flag arguments well; getopts does. getopts is included in the Bourne shell and Bash; getopt needs to be installed separately. getopt allows for the parsing of long options ( --help instead of -h ); getopts does not.

What does getopts mean in Bash?

On Unix-like operating systems, getopts is a builtin command of the Bash shell. It parses command options and arguments, such as those passed to a shell script. How it works. Specifying the optstring. Verbose error checking.

What is Optind in getopts?

According to man getopts , OPTIND is the index of the next argument to be processed (starting index is 1).


2 Answers

Wrong. Actually getopts does support optional arguments! From the bash man page:

If  a  required  argument is not found, and getopts is not silent,  a question mark (?) is placed in name, OPTARG is unset, and a diagnostic message is printed.  If getopts is silent, then a colon (:) is placed in name  and OPTARG is set to the option character found. 

When the man page says "silent" it means silent error reporting. To enable it, the first character of optstring needs to be a colon:

while getopts ":hd:R:" arg; do     # ...rest of iverson's loop should work as posted  done 

Since Bash's getopt does not recognize -- to end the options list, it may not work when -R is the last option, followed by some path argument.

P.S.: Traditionally, getopt.c uses two colons (::) to specify an optional argument. However, the version used by Bash doesn't.

like image 151
Andreas Spindler Avatar answered Sep 21 '22 18:09

Andreas Spindler


getopts doesn't really support this; but it's not hard to write your own replacement.

while true; do     case $1 in       -R) level=1             shift             case $1 in               *[!0-9]* | "") ;;               *) level=$1; shift ;;             esac ;;         # ... Other options ...         -*) echo "$0: Unrecognized option $1" >&2             exit 2;;         *) break ;;     esac done 
like image 22
tripleee Avatar answered Sep 23 '22 18:09

tripleee