Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: OPTIND set incorrectly by getopts for options without arg



Quoting a bit more than I normally would to keep the POSIX text ...
jump to below.

On Tue, Jan 13, 2015 at 12:38 PM, Simon Chiang <simon.a.chiang@xxxxxxxxx> wrote:
>
> func() {
>   OPTIND=1        # reset OPTIND each time in to prevent carryover
>   getopts a:b optvar
>   shift $(( OPTIND -1 ))
>   echo "$OPTIND, $1"
> }
>
> func -a x y z
> output: 3, y      # this is the correct output
>
> func -b x y z
> output: 1, -b     # this is the questionable output
>
>
> Turns out according to the POSIX spec this is a bug (
> http://pubs.opengroup.org/onlinepubs/000095399/utilities/getopts.html)
>
> When the end of options is encountered, the getopts utility shall exit with
> a return value greater than zero; the shell
> variable OPTIND shall be set to the index of the first
> non-option-argument.... Any of the following shall identify the end of
> options: the special option "--", finding an argument that does not begin
> with a '-', or encountering an error.
>
>
> Unless I'm misreading that means that in the first example "y" indicates
> the end of options so the correct output is "3, y".  In the second example
> the "x" indicates the end of options so the correct output is "2, x".  For
> what it's worth bash and dash set OPTIND in this way.

If you add an "echo $?" after the call to getopts in the example
function, you will find that bash getopts has NOT "exit[ed] with a
return value greater than zero".  Neither has zsh getopts.

In zsh, if you add a SECOND call to getopts in the example function,
you will find that the second call DOES exit with a value of 1, and
that WHEN zsh getopts exits with a return value greater than zero,
THEN the value of OPTIND is set as POSIX specifies.

The distinction is the definition of "When the end of options is
encountered."  Zsh does not "encounter" the "end of options" until the
getopts call that actually attempts to "read past" the recognized
options.

You can see this better if you invoke the original example as "func -b
-a x y z".

Whether this is actually wrong or the spec is incomplete, I won't try
to argue here.



Messages sorted by: Reverse Date, Date, Thread, Author