On Fri, Nov 13, 2015 at 10:13 AM, Griff Miller II <griff.mil...@oplink.net>
wrote:

> Configuration Information [Automatically generated, do not change]:
> Machine: x86_64
> OS: cygwin
> Compiler: gcc
> Compilation CFLAGS:  -DPROGRAM='bash.exe' -DCONF_HOSTTYPE='x86_64'
> -DCONF_OSTYPE='cygwin' -DCONF_MACHTYPE='x86_64-unknown-cygwin'
> -DCONF_VENDOR='unknown' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash'
> -DSHELL -DHAVE_CONFIG_H -DRECYCLES_PIDS   -I.
> -I/usr/src/bash-4.3.42-4.x86_64/src/bash-4.3
> -I/usr/src/bash-4.3.42-4.x86_64/src/bash-4.3/include
> -I/usr/src/bash-4.3.42-4.x86_64/src/bash-4.3/lib  -DWORDEXP_OPTION -ggdb
> -O2 -pipe -Wimplicit-function-declaration
>
> -fdebug-prefix-map=/usr/src/bash-4.3.42-4.x86_64/build=/usr/src/debug/bash-4.3.42-4
>
> -fdebug-prefix-map=/usr/src/bash-4.3.42-4.x86_64/src/bash-4.3=/usr/src/debug/bash-4.3.42-4
> uname output: CYGWIN_NT-6.1 MILLERIG1 2.3.0(0.291/5/3) 2015-11-09 10:24
> x86_64 Cygwin
> Machine Type: x86_64-unknown-cygwin
>
> Bash Version: 4.3
> Patch Level: 42
> Release Status: release
>
> Description:
>         getopts doesn't always detect that a required argument is not
> supplied.
>
> Repeat-By:
>         Here is a test script:
>
> #!/bin/bash
>
> # Parse command-line options.
> c=0
> opts=a:b:c
> while getopts $opts opt ; do
>         case $opt in
>                 a)
>                         a=$OPTARG
>                         ;;
>                 b)
>                         b=$OPTARG
>                         ;;
>                 c)
>                         c=1
>                         ;;
>                 ?)
>                         exit 1
>                         ;;
>         esac
> done
>
> echo a = \"${a}\"
> echo b = \"${b}\"
> echo c = $c
>
> % ./myscript -a a
> a = "a"
> b = ""
> c = 0
> % ./myscript -a a -b
> ./test_bash_getopts_unsilent_reporting: option requires an argument -- b
> % ./myscript -a a -b b
> a = "a"
> b = "b"
> c = 0
> % ./myscript -a -b b
> a = "-b"
> b = ""
> c = 0
>
> Note that in the last run, getopts does not detect that nothing was passed
> via -a, even though -a requires it. Instead, it thinks the next switch
> (-b) is the value of -a. Perhaps this was a conscious decision, so that
> values starting with '-' can be passed, but it's a more of a surprise to
> the developer than discovering that the user can't do e.g. ./myscript -a
> -my_a_val .  Can this bug, if it's deemed a bug, be fixed, else the
> manpage updated in the getopts section to make it clear what is going on?
>
> If there is a requirement that the user be able to have optargs that start
> with '-', maybe not allow OPTARG be one of the options in the first
> argument to getopts ($opts in the above script)?
>
> Thank you.
>
>
>
Your opts string needs to begin with a colon to enable silent error
reporting and you need to handle the colon in your case statement as the
condition where a required argument is missing.

Snippets:

opts=:a:b:c

  :) echo "Missing argument for option -$OPTARG" >&2;;

You should escape the question mark since otherwise it's a globbing
character:

  \?) echo "Unknown option: -$OPTARG" >&2; exit 1;;

-- 
Visit serverfault.com to get your system administration questions answered.

Reply via email to