入れ子になった Case 文を使用したパラメータの解析

入れ子になった Case 文を使用したパラメータの解析

私はそれぞれ異なるパラメータセットを使用する2つのモードを持つプログラムを書こうとしています。 @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コマンドライン引数が見つかったらシェル関数を実行します。この関数は、パラメータリストの残りの部分を解析するのに役立ちます。

明らかに、これは特定の状況でのみ機能します。みんなオプションスクリプト(サブコマンドではない)発生今後コマンドラインのすべてのサブコマンド。スクリプトを一度呼び出すと、オプションを含むサブコマンドは1つしかありません。

以下のように、スクリプトがオプションを含む複数のサブコマンドを同時に許可できるようにコマンドライン解析を実装することは不可能ではありません。

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

しかし、今はそれを控えておきます。

おすすめ記事