Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does getopts only work the first time?

Tags:

bash

getopts

Why does this option only work the first time it's used, then ignored every other time? It's like it's being reset when the option is not used.

Here's my function:

testopts() {
    local var="o false"
    while getopts "o" option; do
        case "${option}" in
            o)
                var="o true"
                ;;
        esac
    done
    echo $var
}

When running it, it only returns true when passing the option for the first time.

$ testopts
o false
$ testopts -o
o true
$ testopts -o
o false
like image 611
Jeff Puckett Avatar asked Jan 13 '17 21:01

Jeff Puckett


People also ask

How does getopts work in bash?

If the option is expecting an argument, getopts gets that argument, and places it in $OPTARG. If an expected argument is not found, the variable optname is set to a colon (":"). Getopts then increments the positional index, $OPTIND, that indicates the next option to be processed.

What does colon mean in getopts?

optstring must contain the option letters the command using getopts recognizes. If a letter is followed by a colon, the option is expected to have an argument, or group of arguments, which must be separated from it by white space.

Is getopts case sensitive?

Option letters are case sensitive.

What is the purpose of getopts command?

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.


2 Answers

You need to add this line at top of your function:

OPTIND=1

Otherwise successive invocation of the function in shell are not resetting this back since function is being run in the same shell every time.

As per help getopts:

Each time it is invoked, getopts will place the next option in the shell variable $name, initializing name if it does not exist, and the index of the next argument to be processed into the shell variable OPTIND. OPTIND is initialized to 1 each time the shell or a shell script is invoked.

like image 154
anubhava Avatar answered Sep 24 '22 16:09

anubhava


Resetting OPTIND to 1 works, but it's even better to declare OPTIND as a local variable whenever getopts is used in a function.

See https://eklitzke.org/using-local-optind-with-bash-getopts

like image 45
ryenus Avatar answered Sep 25 '22 16:09

ryenus