悩みながら
シェルスクリプトを
書いているみたいだね?
うん
オプションを扱えるように
できないかと思っているんだけど
これが難しくて…
引数を扱えるなら
オプションも扱いたいと
考えるのはもっともだよね
実はオプションを楽に解釈する
仕組みが用意されているんだ!
えっ!
教えて欲しい!
getopts
は
オプション解析コマンドだよ
専用のコマンドがあるんだね!
getopts
は
色々な要素と組み合わせて
動く前提のコマンドなんだ
少し複雑なので
一緒にスクリプトを
読みながら理解しよう
オプションを解析する
check-opts
スクリプトを
作成しよう!
vim check-opts
うん!
そこに以下の内容を書いてね
#!/bin/bash
# 初期状態
OPT_A=off
OPT_B=off
OPT_C=off
OPT_C_VALUE=
# オプションを処理
while getopts "abc:" OPT
do
case "$OPT" in
a) # a オプション
OPT_A=on
;;
b) # b オプション
OPT_B=on
;;
c) # c オプション(引数付き)
OPT_C=on
OPT_C_VALUE="$OPTARG"
;;
*) # 不正なオプション
echo "エラー: 無効なオプション $OPT が指定されました" >&2
exit 1
;;
esac
done
# オプション処理結果を表示
echo "オプションa: $OPT_A"
echo "オプションb: $OPT_B"
echo "オプションc: $OPT_C"
[ "$OPT_C" == "on" ] && echo "オプションc値: $OPT_C_VALUE"
# 引数を処理
shift $((OPTIND - 1))
for ARG in "$@"
do
echo "引数: $ARG"
done
echo "引数の個数: $#"
ちょっと長かったけど書けたよ!
そうしたら実行権限を与えて実行できるようにしよう
chmod a+x check-opts
これで実行する準備はできたね!
名前のとおりオプションを確認するんだよね?何を指定すればよいかな?
このスクリプトは「オプション引数」を受け取るんだ オプションの指定が終わった後の要素は引数と判断してくれるよ書式は以下のような感じだね
-a
, -b
, -c
オプションを認識するよ-c
は、head -n 1
のように./check-opts [-a] [-b] [-c 値] [引数]...
へぇ…いくつか試してみるね!
./check-opts -a
オプションa: on
オプションb: off
オプションc: off
引数の個数: 0
./check-opts -ab
オプションa: on
オプションb: on
オプションc: off
引数の個数: 0
./check-opts -c X aaa bbb ccc
オプションa: off
オプションb: off
オプションc: on
オプションc値: X
引数: aaa
引数: bbb
引数: ccc
引数の個数: 3
すごい!オプションと引数をちゃんと解析できてる!ショートオプションの同時指定もバッチリ!
getopts
は以下の書式で使うよgetopts オプション文字列 変数名
オプション文字列にはショートオプションとして認識する文字を並べるんだ
オプション文字の後に
:
を指定するとそのオプションは引数を取ると解釈されるんだここの指定は
abc:
だよねgetopts "abc:" OPT
だから
-a
, -b
, -c
オプションを認識して-c
オプションはオプション引数を取るんだね続く変数名の変数に解析したオプション文字が代入されるよこれを
case
文で処理を分けてあげればオプションごとに処理を書けるというわけなんだオプションが指定されていれば対応する変数の値を
off
から on
にしているんだねオプション引数が指定されていた場合
OPTARG
変数にその値が代入されるよこの変数を参照することでどんな値が指定されたかがわかるんだgetopts
はオプション解析を続けられるなら成功そうでないなら失敗を返すんだだから getopts
はwhile
文と一緒に使われるよwhile
文の後にshift
を実行しているね?OPTIND
変数には getopts
が現在解析している引数の番号が入っているんだ1 から始まり次の要素の解析に移る時に値が 1 増加するよだからwhile 文を終えたときの 「最後のオプション + 1」番目の 引数の番号が入っていることになるよ
OPTIND
変数にはオプション解析が終わったときの引数の番号つまりそこで
shift $((OPTIND - 1))
を実行すると解析済みのオプションを全て捨てて残りは全て引数というというわけなんだね…今回は
getopts
でオプションと引数を解析できることを学んだよ!ちょっと書き方が独特で覚えることが多いね…getopts
は今回書いたような決まりきった使い方をするんだ最初はこの check-opts
スクリプトを雛形にして自分のスクリプト用に内容を書き換えてあげるといいよ!