내 스크립트에는 필수 매개변수와 함께 여러 매개변수가 포함되어 있습니다.
while [ "$1" != "" ]; do
case $1 in
-f | --first ) shift
first=$1
;;
-s | --second ) shift
second=$1
;;
* ) break
esac
shift
done
echo "first: "$first" second: "$second
이것은 잘 작동합니다:
$ ./script.sh --first a --second b
first: a second: b
그러나 누군가가 매개변수의 매개변수를 잊어버리면 매개변수를 얻는 것이 잘못될 것입니다.
예를 들어 다음은 작동하지 않습니다.
$ ./script.sh --first --second a
first: --second second:
이는 좋지 않습니다. 첫 번째는 get이지만 두 번째 강제는 처리되지 않습니다.
$ ./script.sh --first a --second
first: a second:
수정하려고 합니다.
* ) break
도착하다:
* ) echo "Bad arguments"
exit 1
이 경우 작동하는 작업은 무엇입니까(강제가 먼저 처리됨):
$./script.sh --first --second b
Bad arguments
하지만 이 경우에는 제대로 작동하지 않습니다(두 번째 항목은 처리하지 않음).
$ ./script.sh --first a --second
first: a second:
답변1
내장된 케이스를 사용하세요 getopts
. 이는 모든 유효한 옵션 문자와 인수가 필요한지 여부를 나열할 수 있는 optstring을 사용합니다(옵션 문자 다음에 따라옴 :
). 예를 들어:
while getopts 'f:s:' opt; do
case "$opt" in
f) first="$OPTARG" ;;
s) second="$OPTARG" ;;
:) usage 1 "-$OPTARG requires an argument" ;;
?) usage 1 "Unknown option '$opt'" ;;
esac
done
shift $((OPTIND -1))
--long 옵션 은 getopts
내장에서 지원되지 않습니다. 이것이 요구 사항인 경우 패키지 getopt
의 프로그램을 사용하십시오 util-linux
. 다른 버전을 사용하지 마십시오. 다른 버전에는 심각한 결함이 있습니다.
TEMP=$(getopt -o 'f:s:' --long 'first:,second:' -n "$0" -- "$@")
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
eval set -- "$TEMP"
while true ; do
case "$1" in
-f|--first) first="$2" ; shift 2 ;;
-s|--second) second="$2" ; shift 2 ;;
--) shift ; break ;;
*) echo 'Internal error!' ; exit 1 ;;
esac
done
노트:
getopts
(s
)는 POSIX 쉘에 내장되어 있으며 이식 가능하고 표준입니다.getopt
(nones
)은 비표준이며 여러 가지 충돌하는 버전이 있으며 대부분 심각한 결함이 있습니다.util-linux
이식성에 신경 쓰지 않는다면 패키지의 버전을 안전하게 사용할 수 있습니다.- 인수가 필요한 옵션이 제공되지 않으면 모두 오류가 발생합니다.
답변2
이는 사건의 텍스트가 무엇이든 shift
으로 전송되기 때문에 발생합니다 $2
. $1
스크립트의 정확한 목적은 불분명하지만, 예를 들어 이를 방지하려면 다음을 수행할 수 있습니다.
while [[ "$1" != "" && "$2" != -* ]]; do
case $1 in
-f | --first ) shift
first=$1
;;
-s | --second ) shift
second=$1
;;
* ) break
esac
shift
done
echo "first: "$first" second: "$second
이렇게 하면 매개변수가 누락된 경우 조작이 방지됩니다.
출력 예:
$ ./script.sh --first a --second b
first: a second: b
$ ./script.sh --first --second b
first: second: