쉘 스크립트에서 스위치를 처리하는 방법은 무엇입니까?

쉘 스크립트에서 스위치를 처리하는 방법은 무엇입니까?

-x매개 변수 대신 및 스위치를 인식하는 내장 도구가 있습니까 --xxxx? 아니면 모든 입력 변수를 반복하고 대시를 테스트한 다음 매개 변수를 구문 분석해야 합니까?

답변1

나는 당신이 bash 또는 이와 유사한 것을 사용하고 있다고 가정합니다. 한 가지 예:

all=false
long=false

while getopts ":hal" option; do
  case $option in
    h) echo "usage: $0 [-h] [-a] [-l] file ..."; exit ;;
    a) all=true ;;
    l) long=true ;;
    ?) echo "error: option -$OPTARG is not implemented"; exit ;;
  esac
done

# remove the options from the positional parameters
shift $(( OPTIND - 1 ))

ls_opts=()
$all && ls_opts+=( -a )
$long && ls_opts+=( -l )

# now, do it
ls "${ls_opts[@]}" "$@"

답변2

사용getopts.

POSIX 사양을 따르기 때문에 이식성이 뛰어납니다. 불행히도 긴 옵션은 지원하지 않습니다.

이것도 보세요getopts 지도 시간bash-hackers wiki 및 this에서 제공질문스택 오버플로에서.

짧은 옵션만 필요한 경우 getopts일반적인 사용 패턴(자동 오류 보고 포함)은 다음과 같습니다.

# process arguments "$1", "$2", ... (i.e. "$@")
while getopts "ab:" opt; do
    case $opt in
    a) aflag=true ;; # Handle -a
    b) barg=$OPTARG ;; # Handle -b argument
    \?) ;; # Handle error: unknown option or missing required argument.
    esac
done

답변3

매개변수를 구문 분석하려면 루프를 작성해야 합니다. 실제로 getopts명령을 사용하면 쉽게 이 작업을 수행할 수 있습니다.

getopts다음은 매뉴얼 페이지의 간단한 예입니다.

aflag=
bflag=
while getopts ab: name
do
    case $name in
    a)    aflag=1;;
    b)    bflag=1
          bval="$OPTARG";;
    ?)    printf "Usage: %s: [-a] [-b value] args\n" $0
          exit 2;;
    esac
done
if [ ! -z "$aflag" ]; then
    printf "Option -a specified\n"
fi
if [ ! -z "$bflag" ]; then
    printf 'Option -b "%s" specified\n' "$bval"
fi
shift $(($OPTIND - 1))
printf "Remaining arguments are: %s\n" "$*"

답변4

나는 최근에 여러 용도로 사용되며 순서에 관계없이 여러 스위치를 허용하는 작업용 스크립트를 작성했습니다. 명백한 법적인 이유로 전체 스크립트를 공개할 수는 없지만(지금은 스크립트가 없다는 것은 말할 것도 없고) 요점은 다음과 같습니다. 서브루틴에 넣고 스크립트 끝에서 호출할 수 있습니다. 의:

options () {

    if [ -n "$1" ]; then # test if any arguments passed - $1 will always exist
        while (( "$#" )); do  # process ALL arguments
            if [ "$1" = ^-t$ ]; then # -t short for "test"
                # do something here THEN shift the argument
                # shift removes it from $@ and reduces $# by
                # one if you supply no argument
                shift

            # we can also process multiple arguments at once
            elif [[ "$1" =~ ^--test=[:alnum:]{1,8}$ ]] && [[ "$2" =~ ^-t2$ ]] && [[ -n "$3" ]]; then # check for 3 arguments
                # do something more then remove them ALL from the arg list    
                shift 3
            else
                echo "No matching arguments!"
                echo "Usage: [script options list here]"
            fi
        done
    else
        echo "Usage: [script options list here]"
        exit 0
    fi
}

options "$@" # run options and loop through/process ALL arguments

bash 스크립트를 400줄/15,000자 미만으로 제한하는 것이 좋습니다. 위에서 언급한 스크립트는 그 크기를 초과하여 다루기가 매우 어려워졌습니다. 나는 작업에 더 적합한 Perl로 다시 작성하기 시작했습니다. Bash에서 스크립트 작업을 할 때 이 점을 명심하세요. Bash는 작은 스크립트와 한 줄짜리 스크립트에 적합하지만 더 복잡한 스크립트는 Perl로 작성하는 것이 더 좋습니다.

위 내용을 테스트하지 않았으므로 작동하지 않을 수도 있지만 여기에서 일반적인 아이디어를 얻을 수 있습니다.

관련 정보