In the following example, -b has not been defined as an option, but `zparseopts` return successfully. Is there a way to let it yield an error when it sees such a case? $ ./main.sh set -- -b -a x -a y zparseopts -D a:=bar echo $? 0 declare -p bar typeset -a bar=( ) declare -p argv typeset -a argv=( -b -a x -a y ) set -- -b -a x -a y zparseopts -D -E a:=bar declare -p bar typeset -a bar=( -a y ) declare -p argv typeset -a argv=( -b ) $ cat ./main.sh #!/usr/bin/env zsh # vim: set noexpandtab tabstop=2: set -v set -- -b -a x -a y zparseopts -D a:=bar echo $? declare -p bar declare -p argv set -- -b -a x -a y zparseopts -D -E a:=bar declare -p bar declare -p argv -- Regards, Peng
On 2 Dec 2018, at 16:28, Peng Yu <pengyu.ut@gmail.com> wrote:
>In the following example, -b has not been defined as an option, but
>`zparseopts` return successfully. Is there a way to let it yield an
>error when it sees such a case?
Not that i know of. If it didn't swallow up `--` you could check to see if the
first element remaining in argv is any other string beginning with a hyphen, but
since it does you can only rely on that method when no other argument to your
function/script can ever start with a hyphen:
% myfunc() {
local -a opts
zparseopts -D -a opts a b c
print -r - $? / $opts / $@
}
% myfunc -a -b -foo
0 / -a -b / -foo
% myfunc -a -b -- -foo
0 / -a -b / -foo
If you're certain that that's the case (e.g., the first operand must be a digit
or an absolute path or something), then just abort if `[[ $1 == -* ]]`
dana
On 2 Dec 2018, at 18:13, dana <dana@dana.is> wrote:
>Not that i know of. If it didn't swallow up `--` you could check to see if the
>first element remaining in argv is any other string beginning with a hyphen
After i hit send it occurred to me that you can deal with this if you use -E,
but you'll have to do a second pass yourself to catch any bad options that it
leaves behind:
myfunc() {
local i
local -a opts
zparseopts -D -E -a opts a b: c
print -r "options: $opts"
for (( i = 1; i <= $#; i++ )); do
[[ $argv[i] == (-|--) ]] && {
argv[i]=()
break
}
[[ $argv[i] == -* ]] && {
print -ru2 "bad option: $argv[i]"
return 1
}
done
print -r "operands: $*"
}
I *think* that handles everything...?
dana