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 배우기.
네 번째 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
.