getopt
概要
getoptは主にシェルスクリプトでコマンドオプションを使いやすい形に変形するために使う。いくつか書式があるが、伝統的なgetoptでは以下のように使う。
$getopt optstring parameters
引数はoptstringとparamtersに分かれる。optstringにはオプションと認識する一文字を連続して書く。その文字の最後に:をつけた場合は、そのオプションはパラメータをとるという意味になる。parametersは、解析する引数を書く。
伝統的なコマンド使用例
例えば ab:cとした場合は、-a -b -cをオプションとして認識し、-bオプションはパラメータをとることになる。出力の順番はオプションと必要があればそのパラメータがすべて出力され、'--'を出力後にどれでもないものが出力される。
$ getopt ab:c -a
-a --
上の例では、parametersが-aオプションのみなので-aと'--'が出力される。
-a --
$getopt ab:c -b
getopt: オプションには引数が必要です -- b
--
今度は-bオプションを指定したが、-bオプションには引数が必要となるためエラーとなる。
getopt: オプションには引数が必要です -- b
--
$ getopt ab:c -b aaa
-b aaa --
上記のように書くと、aaaが-bオプションの引数になるので正常に出力される。
-b aaa --
$ getopt ab:c -b aaa -a bbb -c
-b aaa -a -c -- bbb
-aの後にbbbを書くと、-aは引数をとらないのでbbbはオプションでもオプションの引数でもないことになり、--の後ろに出力され、順番が入れ替わる。
-b aaa -a -c -- bbb
$ getopt ab:c -b aaa -a -c -d
getopt: オプションが違います -- d
-b aaa -a -c --
-dはoptstringに定義されていないため、エラーとなる。
getopt: オプションが違います -- d
-b aaa -a -c --
このようにgetoptでオプション文字並びにオプションの引数チェックとオプション文字でもオプションの引数でもないものを後ろに並べかえてくれる。
拡張コマンド使用例
GNUのgetoptの場合は以下のような書き方ができる。(他にもいくつか書き方があるが詳細はgetop(1)を参照のこと)
$getopt -o optstring -l longoptstring -- parameters
-oは短いオプションを上記と同じ形式で記述する。-lには、長いオプション名を','で区切りながら記述できる。また、短いオプションと同様に最後に':'をつけるとそのオプションは引数を取ることになる。paramtersで長いオプションは'--'で始まる。
$getopt -o ab:c -l dfg,hij: -- -a --dfg abc --hij aaa
-a --dfg --hij 'aaa' -- 'abc'
--dfgと--hijがオプションとして認識され、aaaは--hijの引数となる。また、この書式を使うとシェルでのメタ文字の展開を避けるため、オプションの引数とオプション文字でもオプションの引数でもないものはシングルクォートされて出力される。
-a --dfg --hij 'aaa' -- 'abc'
シェルスクリプト利用例
シェルスクリプトで使う場合は以下のようにして使う。
OPTIONS=`getopt -o ab:c --long dfg,hij: -- "$@"`
if [ $? != 0 ] ; then
exit 1
fi
eval set -- "$OPTIONS"
while true; do
case "$1" in
-a)
# -aのときの処理
shift
;;
-b)
# -bのときの処理
shift 2
;;
-c)
# -cのときの処理
shift
;;
--dfg)
# --dfgのときの処理
shift
;;
--hij)
# --hijのときの処理
shift 2
;;
--)
shift
break
;;
*)
echo "Internal error!" >&2
exit 1
;;
esac
done
# オプションでもオプションの引数でもないものの処理
$@はシェルスクリプトの位置パラメータ($1,$2,...)に展開されるので、それをgetoptにかけ、オプションとそのパラメータが先になるように並べ変える。その際、認識できないオプションがあったり、オプションのパラメータが存在しない場合はエラーとなる。その出力結果をもう一度「set -- 」で位置パラメータに入れ直す。ただし、シェルの特別な文字を展開しないように、$OPTIONSをダブルクォート("$OPTIONS")としてパラメータ展開を行っているため、evalとして実行する。(そうしないと、setのパラメータとして展開されるので、ひとつの単語とみなされ$1にまとめて設定されてしまう。evalをつけるとevalのパラメータとして展開された後、「set --」が実行されるため、スペース区切りでそれぞれ位置パラメータに設定される。)
if [ $? != 0 ] ; then
exit 1
fi
eval set -- "$OPTIONS"
while true; do
case "$1" in
-a)
# -aのときの処理
shift
;;
-b)
# -bのときの処理
shift 2
;;
-c)
# -cのときの処理
shift
;;
--dfg)
# --dfgのときの処理
shift
;;
--hij)
# --hijのときの処理
shift 2
;;
--)
shift
break
;;
*)
echo "Internal error!" >&2
exit 1
;;
esac
done
# オプションでもオプションの引数でもないものの処理
■ 参考資料
Manpage of GETOPTManpage of BASH
0 件のコメント:
コメントを投稿