我正在尝试使用 ksh 内置 getopts 来管理 ksh 代码的运行时选项。
当使用需要和参数的选项时,我不断收到错误:“未知的选项参数值”。
这是有问题的代码:
$ cat usage.sh
#!/bin/ksh
#set -xv
USAGE=$'[-?\n@(#)$Id: '"script_name"
USAGE+=$'\n'"script_version"$' $\n]'
USAGE+="[m:mode?Sets notification mode.]:[mode:=ALL]"
USAGE+="{[mode=SMS?SMS notification][mode=MAIL?EMAIL notification][mode=ALL?EMAIL and SMS notification]}"
while getopts "$USAGE" optchar;
do
case $optchar in
m) case "$OPTARG" in
MAIL) echo -e "-m MAIL:\tOK!"
;;
SMS) echo -e "-m SMS:\tOK!"
;;
ALL) echo -e "-m ALL:\tOK!"
;;
esac
;;
esac
done
这里有一些输出:
$ ./usage.sh --man
SYNOPSIS
./usage.sh [ options ]
OPTIONS
-m, --mode=mode Sets notification mode.
mode=SMS
SMS notification
mode=MAIL
EMAIL notification
mode=ALL
EMAIL and SMS notification
The default value is ALL.
IMPLEMENTATION
version script_name script_version
$ ./usage.sh -m SMS
./usage.sh: -m: SMS: unknown option argument value
Usage: ./usage.sh [-m mode]
$ ./usage.sh -m pippo
./usage.sh: -m: pippo: unknown option argument value
Usage: ./usage.sh [-m mode]
我想出了下面那个极其复杂的 optstringO'Reilly's - 学习 Korn Shell。
如果我评论第四个 USAGE 定义行选项参数值,这就是我得到的:
$ ./usage.sh --man
SYNOPSIS
./usage.sh [ options ]
OPTIONS
-m, --mode=mode Sets notification mode. The default value is ALL.
IMPLEMENTATION
version script_name script_version
$ ./usage.sh -m SMS
-m SMS: OK!
$ ./usage.sh -m pippo
(nothing)
我将其理解为 getopts 不检查参数允许的值。
如何让 getopts 检查不允许的参数值,而不阻止允许的参数值?
$ ksh --version
version sh (AT&T Research) 93u+ 2012-08-01
答案1
看来您设置了“ALL”模式选项两次:
USAGE+="[m:mode?Sets notification mode.]:[mode:=ALL]"
USAGE+="{[mode=SMS?SMS notification][mode=MAIL?EMAIL notification][mode=ALL?EMAIL and SMS notification]}"
只需删除第一个:
USAGE+="[m:mode?Sets notification mode.]:"
USAGE+="{[mode=SMS?SMS notification][mode=MAIL?EMAIL notification][mode=ALL?EMAIL and SMS notification]}"
答案2
将此作为备忘录发布,以下代码按预期工作:
#!/bin/ksh
#set -xv
USAGE=$'[-?\n@(#)$Id: '"script_name"
USAGE+=$'\n'"script_version"$' $\n]'
USAGE+="[m:mode?Sets notification mode.]:[mode:=ALL]"
USAGE+="{[S:SMS?SMS notification][M:MAIL?EMAIL notification][A:ALL?EMAIL and SMS notification]}"
while getopts "$USAGE" optchar;
do
case $optchar in
m) case "$OPTARG" in
M) echo -e "-m MAIL:\tOK!"
;;
S) echo -e "-m SMS:\tOK!"
;;
A) echo -e "-m SA:\tOK!"
;;
esac
;;
esac
done
这是输出:
$ ./usage.sh --man
SYNOPSIS
./usage.sh [ options ]
OPTIONS
-m, --mode=mode Sets notification mode.
SMS SMS notification
MAIL EMAIL notification
ALL EMAIL and SMS notification
The default value is ALL.
IMPLEMENTATION
version script_name script_version
$ ./usage.sh -m SMS
-m SMS: OK!
$ ./usage.sh -m pippo
./usage.sh: -m: pippo: unknown option argument value
Usage: ./usage.sh [-m mode]
这种方式-m SMS
相当于-m S
.