중첩된 Case 문을 사용하여 매개변수 구문 분석

중첩된 Case 문을 사용하여 매개변수 구문 분석

저는 각각 다른 매개변수 세트를 사용하는 두 가지 모드가 있는 프로그램을 작성하려고 합니다. @geekosaur가 언급한 대로 중첩된 사례 문을 구현해 보았습니다.여기case "$1", 패턴과 인수를 통해 case "$2".

--help사용 가능한 모드를 설명하는 프로그램에 대한 일반 옵션과 --help매개변수를 설명하는 각 모드에 대한 개별 옵션이 있습니다 .

내가 실행하면 :

./program.sh --help일하다

./program.sh mode1 --help일하다

./program.sh mode1 --unknown작동합니다(알 수 없는 옵션을 올바르게 캡처하고 모드 1에 대한 사용 함수를 호출합니다).

하지만:

./program.sh mode1 --option1 file

ERROR: unknown parameter file

즉, "option1" 키의 값이 아닌 "file"을 매개변수로 인식합니다.

어떻게 해야 하나요? "교대 근무"를 엉망으로 만들고 있습니까? 아니면 중첩 루프가 필요합니까?

(단순화를 위해 아래 코드에는 "mode1"만 표시됩니다.)

#!/bin/bash

usage_general() {
    echo "Usage: ProgramName [modes]"
    echo ""
    printf "%-10s %s\n" "mode1" "Run subprogram 1."
    printf "%-10s %s\n" "mode2" "Run subprogram 2."
}

usage_mode1() {
    echo "Usage: ProgramName mode1 [options]"
    echo ""
    printf "%-10s %s\n" "-1 | --option1" "Arg 1 for mode1"
    printf "%-10s %s\n" "-2 | --option2" "Arg 2 for mode1."
}


while [[ $# -gt 0 ]]
do
    case "$1" in
    -h | --help)
        usage_general
        exit
        ;;

    mode1)

        case "$2" in
        -h | --help)
            usage_mode1
            exit
            ;;
        -1 | --option1)
            val1="$3"
            shift 2
            ;;
        -2 | --option2)
            val2="$3"
            shift 2
            ;;
        *)
            echo "ERROR: unknown parameter $2"
            usage_mode1
            exit 1
            ;;
        esac
        ;;

    *)
        echo "ERROR: unknown parameter $1"
        usage_general
        exit 1
        ;;
    esac
done

답변1

shift 2내부적으로 사용하는 경우 및 파일 이름은 case제거되지만 파일 이름은 제거 되지 않습니다 .$1$2$3

mode1및 하위 명령에 대한 옵션을 구문 분석하려면 별도의 루프를 수행해야 합니다 mode2.

스크립트의 명령줄 인수에서 하위 명령이 발견되면 나머지 옵션과 옵션 인수가 해당 하위 명령에 속한다고 가정하면 다음과 같이 구문 분석을 분할할 수 있습니다.

run_mode1 () {
    while [ "$#" -gt 0 ]; do
        case "$1" in
        -h | --help)
            usage_mode1
            exit
            ;;
        -1 | --option1)
            val1="$2"
            shift 2
            ;;
        -2 | --option2)
            val2="$2"
            shift 2
            ;;
        *)
            echo "ERROR: unknown parameter $1"
            usage_mode1
            exit 1
            ;;
        esac
    done

    # code for actually running mode1 goes here
}

while [[ $# -gt 0 ]]
do
    case "$1" in
    -h | --help)
        usage_general
        exit
        ;;

    mode1)
        shift
        run_mode1 "$@"
        break
        ;;

    *)
        echo "ERROR: unknown parameter $1"
        usage_general
        exit 1
        ;;
    esac
done

여기서는 mode1명령줄 인수가 발견되면 쉘 함수를 실행합니다. 이 함수는 매개변수 목록의 나머지 부분을 구문 분석하는 역할을 합니다.

분명히 이것은 특정 상황에서만 작동합니다.모두옵션스크립트(하위 명령 아님) 발생앞으로명령줄에 있는 모든 하위 명령. 스크립트를 한 번 호출할 때 옵션이 포함된 하위 명령은 하나만 있을 수 있습니다.

아래와 같이 스크립트가 옵션이 포함된 두 개 이상의 하위 명령을 동시에 허용할 수 있는 방식으로 명령줄 구문 분석을 구현하는 것은 불가능하지 않습니다.

./script.sh ...options... mode1 ...options... mode2 ...options...

하지만 지금은 그것을 제쳐두겠습니다.

관련 정보