KSH - 内置 getopts 未知选项参数值

KSH - 内置 getopts 未知选项参数值

我正在尝试使用 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.

相关内容