Frage

Whenever I use getopts and i don't give any argument for a given flag I get the following message: "option requires an argument -- d"

I would like to remove this message and allow the user to retype the options using the read command.

Here is my case in the getopts:

if [ $# -lt $OPTIND ]; then
    echo "Option -d argument missing: needs 2 args"
    echo "Please enter two args: <arg1> <arg2>"
    read d_ID d_SIZE
    echo "disc $d_ID $d_SIZE" >> $FILENAME
else
    d_ID=$OPTARG
    eval d_SIZE=\$$OPTIND
    echo "disc $d_ID $d_SIZE" >> $FILENAME
fi
;;
War es hilfreich?

Lösung

I think the behavior you want is a bad idea; there exist programs that take options with optional arguments, and they work nothing like what you describe. Your approach will likely confuse your users; it will make it difficult for other programs to interoperate with it; and it will limit the future extensibility of your script. (Imagine you want to add another option later on. your_script.sh -d -e will pass -e as an argument to -d, even if the user wanted to use -d with no argument and intended -e as a separate option.) And it's especially bizarre to expect one argument if it's on the command line, but two arguments from standard input.

That said . . .

To achieve some of the effect of an optional option-argument, you can tell getopts to be "silent" (that is, to use "silent error reporting") by putting a colon : at the beginning of the option string. (For example, instead of getopts d: ..., you would write getopts :d: ....) Then, when an option's argument is missing, it will set the option-name to : (instead of d) and OPTARG to the option-name (namely d, instead of the option-argument).

For example, the below script can be called either as script.sh -d foo or as script.sh -d, with the latter causing the user to be prompted to type a value:

#!/bin/bash

if getopts :d: arg ; then
    if [[ "$arg" == d ]] ; then
        d="$OPTARG"
    else
        read -p 'Enter d: ' d
    fi
    echo "d is: $d"
else
    echo 'no d'
fi

Resulting in:

$ ./script.sh
no d

$ ./script.sh -d
Enter d: x
d is: x

$ ./script.sh -d y
d is: y
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top