
kshコードのランタイムオプションを管理するためにksh組み込みgetoptsを使用しようとしています。
必須オプションと引数を持つオプションを使用すると、「不明なオプション引数値」というエラーが発生し続けます。
問題のコードは次のとおりです。
$ 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]
私は以下で非常に複雑なoptstringを思いついた。O'Reilly's - Korn Shellを学ぶ。
4番目の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」モードオプションを2回設定したようです。
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
。