옵션이 포함된 쉘 스크립트

옵션이 포함된 쉘 스크립트

저는 최대 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이미 설정되어 있기 때문에 나쁜 변수입니다.

관련 정보