Why don't I have a space between the option and the optional argument using getopt?

When using getopt parameters to parse command line parameters, you can put a space between the parameter flag and the argument for the necessary arguments, but not for the optional arguments. Optional arguments will only be parsed if they are right after the option.

TEMP=`getopt -op:q:: -n 'mkqueue.sh' -- " $@ "` if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi # Note the quotes around `$TEMP': they are essential! eval set -- "$TEMP" # Now go through all the options while true ; do case "$1" in -p) echo "Option p, argument \`$2'" ; shift 2 ;; -q) case "$2" in "") echo "Option q, no argument"; shift 2 ;; *) echo "Option q, argument \`$2'" ; shift 2 ;; esac ;; --) shift ; break ;; *) echo "Internal error!" ; exit 1 ;; esac done 

(Based on this: http://software.frodo.looijaard.name/getopt/docs/getopt-parse.bash )

When I run the script without an additional argument, it works:

 ./mkqueue.sh -p adfsa -q Option p, argument `adfsa' Option q, no argument 

If I try to add an optional argument to -q with a space between it, it does not work:

 ./mkqueue.sh -p adfsa -q sdfasdfa Option p, argument `adfsa' Option q, no argument 

It works if there is no space between the option and the argument, although the required arguments work with space:

 ./mkqueue.sh -p adfsa -qsdfasdfa Option p, argument `adfsa' Option q, argument `sdfasdfa' 

Is there a fix for this?

+6
source share
1 answer

This restriction is fixed in the man page for getopt :

A simple short option is a `- 'followed by a short option symbol. If an option has the required argument, it can be written immediately after the option symbol or as the next parameter (i.e., separated by a space on the command line). If an option has an optional argument, it should be written immediately after the option symbol, if any.

Although getopt allows "optional option arguments", they are usually considered bad. For example, the Posix Utility Syntax Guide :

Guideline 7 . Optional arguments should not be optional.

The main reason for this tutorial is that, by convention, the command line option argument can be any string. For example, it may look like another option. This may be a literal string -- which usually indicates the end of the list of options. This may be an empty string. Everything.

The problem with “optional argument arguments” is that the only way to find out that an optional argument argument is not specified is to recognize the next argument as an option or -- . But this means that the value of an optional argument cannot begin with - .

Alternatively, you can choose the solution made by the getopt command-line utility, which requires that the optional argument immediately match this option, without any intermediate space (that is, in the same word). But in this case, the optional argument cannot be an empty string.

Instead of creating complex rules to resolve these ambiguities, the simple solution recommended by Posix (and, with much less authority, by me) is to optionally not allow parameter arguments. If there is a common value for the command-line option, and you want to simplify the life of the user without requiring input, then implement two different command-line options, one of which takes an argument, and the other does not. Common methods include using a lowercase character for a version with no argument and the corresponding uppercase character for a version with an argument, or using a long option ( --option ) for that version.

For those who prefer a tight and packed explanation, the Posix explanation explains that:

Guide 7 allows any string to be an option argument; The argument parameter can begin with any character, it can be - or -- and it can be an empty string. For example, the commands pr -h - , pr -h -- , pr -h -d , pr -h +2 and pr -h '' contain the argument parameters - , -- , -d , +2 and an empty string, respectively . And vice versa, the command pr -h -- -d treats -d as a parameter, and not as an argument, because -- here is the argument of the parameter, not the separator.

+8
source

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


All Articles