3

I use the "getopts" ksh built-in to handle command-line options, and I'm looking for a clean/standard way to "unset" an option on the command line. I don't know if this is a technical question about getopts or more of a style/standards question. Anyway, I understand that getopts processes its args (by default $*) from left to right, and I'm hoping to use that to allow a second specification of an option to "turn off" an option.

For options that take an option argument, this isn't a problem. In my getopts processing case statement I just say, for the "-x" option, for example:

x ) x_arg=$OPTARG
    ;;

and the last instance of "-x" on the command line wins, which is what I want.

The problem comes in with options that don't take an option argument. If the option is just a switch/flag then my case statement would just have something like:

x ) x_specified=1
    ;;

With an option like this all I can really do is add "-x" again on the command line, and the same thing just happens: "x_specified=1" is executed again. What's the best/easiest/simplest/standardest way to "unset x_specified"? That's my question.

I had hoped to invoke the getopts functionality that allows either "+" or "-" to precede option letters, but it seems there's no way to tell within the getopts processing loop whether "+" or "-" was used. If there were a way to tell then I could adopt the standard that "+" means to turn off the setting. The other thing I could do is something like:

x ) if [[ -z $x_specified ]] ; then
        x_specified=1
    else
        unset x_specified
    fi
    ;;

Now the "-x" option would be a toggle; each time it's seen on the command line the setting changes. However, I'd like a way on the command line to say, "turn off the -x setting," and not just "toggle the -x setting." I could also pick some other letter, e.g. "X", as the way to turn it off, but many of my scripts already use both the upper case and lower case versions of the same letter to mean different things, and if I have to pick some other random letter to mean "turn off -x" then that's not very mnemonic, and my scripts are hard enough to learn how to use already.

Finally, you may ask, "If you want -x off on the command line, why are you turning it on in the first place?" Option processing in my scripts goes through a multi-step process. Command-line options are checked, and also a config file is checked for options, and there's a precedence between the two. This all works fine for options that take an option argument, but the scheme falls apart for options that don't.

1 Answers1

1

I've got ksh93, and it allows + options if the the optstring starts with "+":

while getopts +abc opt; do
    echo "have option '$opt'"
done

Running this:

$ ./args.ksh -a -b -c +b -b foo 
have option 'a'
have option 'b'
have option 'c'
have option '+b'
have option 'b'
$ ksh --version
  version         sh (AT&T Research) 93u+ 2012-08-01

One ambiguity I see in the man page: it says that the ":" option must also be the "leading" character in the optstring.

http://linux.die.net/man/1/ksh93

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • That works fine. If the opt var is seen to have a leading "+" then I can do what I need to do in my getopts loop. Regarding the leading ":" in the option string, I think that's just to control the behavior when an invalid option is seen. So, if you want to allow "+" as well as "-" to introduce options, add "+" to the beginning of the option string. If you also want to invoke the special behavior associated with ":" then add ":+" to the beginning of the option string. – Matt Miller Aug 09 '13 at 00:03