Ksh

KSH - 內置 getopts 未知選項參數值

  • September 27, 2016

我正在嘗試使用 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]

*在O’Reilly 的《學習 Korn Shell 》*之後,我想出了那個極其複雜的 optstring 。

如果我評論第四個 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

將此作為備忘錄發布,以下程式碼按預期工作:

#!/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

看來您設置了兩次“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]}"

引用自:https://unix.stackexchange.com/questions/305018