저는 최대 2개의 옵션을 허용하는 쉘 스크립트를 작성 중입니다. 그러나 문제가 있습니다. 도와주세요? (스크립트 이름이 이라고 가정합니다 command
.)
#!/bin/bash
PROGNAME=$(basename $0)
for OPT in "$@"
do
echo "OPT: $OPT"
case "$OPT" in
'-p' | '--password' )
if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]
then
echo "$PROGNAME: option requires an argument -- '$(echo $1 | sed 's/^-*//')'"
exit 2
fi
PASSWORD="$2"
shift 2
;;
'-u' | '--user' )
if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]
then
echo "$PROGNAME: option requires an argument -- '$(echo $1 | sed 's/^-*//')'"
exit 2
fi
USER="$2"
shift 2
;;
* )
echo "$1"
echo "$PROGNAME: illigal option or argument -- '$(echo $1 | sed 's/^-*//')'"
exit 1
;;
esac
done
echo "GOOD"
테스트 1
$./command
GOOD
테스트 2
$./command -u user
OPT: -u
OPT: user
command: illigal option or argument -- ''
(네 번째 행은 비어 있습니다.)
테스트 3
$./command -u user -p passwd
OPT: -u
OPT: user
-p
command: illigal option or argument -- 'p'
-u, --user, -p 및 --password에서도 마찬가지입니다. 3가지 질문이 있습니다.
1) test2, test3에 "OPT: user"가 나타나는 이유는 무엇입니까?
2) 이 코드에 옵션을 주면 왜 오류가 발생합니까?
3) 이 코드를 어떻게 수정하나요? 당신의 도움에 정말 감사드립니다!
답변1
확장은 "$@"
루프 시작 부분에서 발생합니다 . for
내부적으로는 shift
아무런 영향도 미치지 않습니다 .
예를 들어
for a in "$@"
do
echo OPTION: $a
shift 2
done
이것으로:
$ bash x a b c d e f
OPTION: a
OPTION: b
OPTION: c
OPTION: d
OPTION: e
OPTION: f
shift
아무것도 이루어지지 않은 것을 볼 수 있습니다
대신 매번 재평가하고 싶습니다.
$ cat x
while [ $# -gt 0 ]
do
a="$1"
echo OPTION: $a
shift 2
done
$ bash x a b c d e f
OPTION: a
OPTION: c
OPTION: e
(이보다 더 나은 테스트를 수행해야 합니다. 홀수 개의 인수를 전달하면 이 예제 코드는 실패하기 때문에 종료되지 않습니다 shift 2
.)
답변2
나는 while/shift 루프를 사용하곤 했습니다.
#! /bin/bash
PROGNAME=$(basename $0)
while [ -n "$1" ]
do
echo "OPT: $1"
case "$1" in
--user=* )
if [[ "$1" =~ --user=(.+) ]]
then
USER=${BASH_REMATCH[1]}
else
echo "$PROGNAME: option requires an argument -- $1"
exit 2
fi
;;
-u )
if [ -z "$2" ]
then
echo "$PROGNAME: option requires an argument -- $1"
exit 2
fi
USER="$2"
shift
;;
* )
echo "$PROGNAME: illigal option or argument -- $1"
exit 1
;;
esac
shift
done
[ -n "$USER" ] && echo "USER: $USER"
echo "GOOD"
하지만 $USER
이미 설정되어 있기 때문에 나쁜 변수입니다.