[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Handling options with optional arguments with getopts
From: |
nigelberlinguer |
Subject: |
Handling options with optional arguments with getopts |
Date: |
Fri, 27 Aug 2021 17:20:39 +0000 |
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Friday, August 27, 2021 4:02 PM, Robert Elz <kre@munnari.OZ.AU> wrote:
> Date: Fri, 27 Aug 2021 15:05:52 +0000
> From: nigelberlinguer via Bug reports for the GNU Bourne Again
> SHell <bug-bash@gnu.org>
>
> Message-ID:
> <0IgsinjPxg5VSubCxyc64u9axdDTEubUNcQFmIaPyduotl2CyQ9g71uoLtpmXL2hUph1_eHzVRnEZ7vyyHFKqqy3OlPydQXccd2CkHyzpjA=@protonmail.com>
>
>
> | I am trying to use getopts so one of the options can use
> | an optional argument.
>
> getopts is required by POSIX to:
>
> The getopts utility shall retrieve options and option-arguments
> from a list of parameters. It shall support the Utility Syntax
> Guidelines 3 to 10, inclusive, described in XBD Section 12.2
>
> XBD 12.2 guideline 7 is:
>
> Guideline 7: Option-arguments should not be optional.
>
> That is, if you want to be able to give an option arg, or not give one,
> those should be implemented as 2 separate options.
It should be noted though, that the POSIX requirement by "Guideline 7"
is not guided by actual portability in the technical sense but by a
rule written in the POSIX standard. Perhaps there should be an update
to POSIX on what is actually portable or not
> That said, getopts also:
>
> If an option-argument is missing:
>
> If the first character of optstring is a <colon>,
>
> the shell variable specified by name shall be set to the
> <colon> character and the shell variable OPTARG shall be
>
> set to the option character found.
>
>
> which means that you can do
>
> while getopts :abc:d var
> do
> case "${var}" in
> a) .... ;;
> b) .... ;;
> c) carg=${OPTARG}; .... ;;
> d) .... ;;
> :) case "${OPTARG}" in
> c) carg=Missing; .... ;;
> *) usage ... ;;
> esac
> ?) usage Bad arg "${OPTARG}" ... ;;
> esac
> done
>
> or something like that ... but beware that it only actually works
> when the option that might have an arg is last in the args given, so
> in the case above
>
> script -a -c
>
> would do what you want, but
>
> script -c -a
>
> would not, there "-a" is the arg to the -c option, not an option itself.
> There is no way (certainly no portable way) around that.
>
> kre
I have seen the following workaround, where tho options that allows an
optional argument is defined with no arguments in shortopts.
local vb=1 sort=0
local OPTIND OPTARG
local shortopts="Vuhvs"
while getopts $shortopts arg; do
case $arg in
("V") printf '%s\n' "Version" ; return ;;
("u") printf '%s\n' "usage" ; return ;;
("h") printf '%s\n' "help" ; return ;;
("v")
# Allows argument to be optional.
# Defines option with no arguments in shortopts.
nextarg=${!OPTIND}
if [[ (-n "$nextarg") && ("$nextarg" != -*) ]] ; then
OPTIND=$((OPTIND + 1))
vb="$nextarg"
fi
;;
#.............................
("s") sort=1 ; shift ;; # shifts arg by 1
#.............................
(?)
pfm "Invalid option: -${OPTARG}."
pfm "Invoke \`myfunc -h\` for details."
break
;;
esac
done
I also wonder whether the "shift" command is used with `getopts`. I see people
use
the `shift` command when doing their own parsing; and when others use `getopt`.
- Handling options with optional arguments with getopts, nigelberlinguer, 2021/08/27
- Re: Handling options with optional arguments with getopts, Robert Elz, 2021/08/27
- Handling options with optional arguments with getopts,
nigelberlinguer <=
- Re: Handling options with optional arguments with getopts, Robert Elz, 2021/08/27
- Handling options with optional arguments with getopts, nigelberlinguer, 2021/08/27
- Handling options with optional arguments with getopts, nigelberlinguer, 2021/08/27
- Handling options with optional arguments with getopts, hancooper, 2021/08/28
- Re: Handling options with optional arguments with getopts, Robert Elz, 2021/08/28
- Handling options with optional arguments with getopts, hancooper, 2021/08/28