getoptsコマンド - 簡易的なオプション解析コマンド

スポンサーリンク

getoptsコマンドはbashでの組み込みコマンドのひとつで、シェルスクリプトでオプションを実装する際に役立つコマンドになります。getoptsコマンドは使用するオプションのためのオプション文字列とオプションを解析した結果を入れる変数を引数にして、ループを利用してオプションを解析します。

ただし、getoptsコマンドで利用できるオプションの種類には制限があります。また、オプションでの引数も一つに制限されています。しかし、簡易的なオプションのあるシェルスクリプトを作成するのに便利であり、より洗練されたスクリプトを作成するのに役立ちます。

スポンサーリンク

getoptsコマンドで解析できるオプションについて

getoptsコマンドは一文字の-a, -b, -cのような、'-'と一文字のアルファベットを組み合わせたオプションを解析できます。

また、オプションには一つの引数を指定できます。

'-'と複数のオプションを組み合わせた以下のような形式もオプションとして指定できます。

ロングオプションや複雑なオプションを利用したい場合はgetoptコマンドや自前のオプション解析器を利用する必要があります。

引数なしのオプションの利用

getoptsコマンドは2つの引数を準備して利用します。

1つ目はオプションに使用する1文字オプションを列挙したオプション文字列になります。
2つ目はオプションの解析結果を入れる変数になります。

2引数のgetoptsコマンドは位置パラメータを解析して、2つ目の引数の変数に結果を入れます。
また、無効なオプションが見つかった場合は'?'の文字が変数に入ります。'?'は任意の一文字に該当するのでエスケープ処理を行っています(ただし、case文の最後の処理になっているので必要性はないかもしれません)。

getopts_demo1.sh

実行例

3引数以上でgetoptsコマンドを利用する場合は、位置パラメータの代わりに3つ目以降の引数が利用されます。

オプションのあるスクリプトについて

上のgetopts_demo1.shではオプションが入ってきたら、echo文を実行するといったプログラムの処理を行うような実装になっています。このとき、同じオプションが複数回実行された場合、

のように実行されます。これが意図したものなのかは分かりませんが、オプションの処理としては通常、望ましいものではありません。

なので、オプションが入ってきたの時の処理は、可能な限り変数にフラグを立てるやデータを入れる等のような文だけにして置き、オプションの解析が終わった後で、プログラムの処理を行ったほうがプログラムの制御が行いやすい構造になります。

また、このようにすることでデフォルト値を設定でき、どのオプションを常に利用するのか又はしないのかの選択もできるようになります。

getopts_demo2.sh

実行例

また、関数に慣れているならgetopts_demo2.shのスクリプトは

getopts_demo3.sh(一部省略)

のようなブロックにしても良いかもしれません(関数の中身は一部のみ記述し、他は省略しています)。

変数のスコープは、関数が終了するまで生きています。また、変数を宣言した関数が呼び出した関数内でもその変数は参照できます。ただし、そのような変数の参照は保守性の観点からむやみに使う方法ではなく、使うべき場所を制限して利用すべきかもしれません。

サイレントモード

使用するオプションの文字列の最初の文字を":"にするとgetoptsコマンドはサイレントモードになります。独自のエラーメッセージを設定したい場合に利用できます。

このサイレントモードのとき、無効のオプションが見つかった時にそのオプションは変数OPTARGに入ります。また、引数が必要なオプションの場合は変数に':'が入り、変数OPTARGに該当しているオプションの文字が入ります。

getopts_demo4.sh(opt_parse関数のみ)

実行例

':'と'\?'の位置を入れ替えると'\?'のエスケープ処理の必要性はなくなるかもしれません。

引数があるオプションの利用

引数があるオプションを利用したい場合は、使用するオプションの後に':'の文字を入れます。
また、オプションの引数は変数OPTARGに入ります。

getopts_demo5.sh

実行例

複数の引数のオプションとして利用する場合は、例えば、カンマ区切りの文字列を要求して、その文字列を区切り文字で分割することで複数の引数を要求するオプションのように利用できます。

文字列を配列にする方法はreadコマンドを利用する方法や配列のリテラルを利用する方法があります。以下は配列のリテラルを利用した方法になります。

getopts_demo6.sh(opt_parse関数とopt_process関数、中身は一部省略)

実行例

参考

Bash Reference Manual

POSIX getopts