私はそれぞれ異なるパラメータセットを使用する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...
しかし、今はそれを控えておきます。