本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回は、シェルスクリプト内などでオプションを解析する「getopt」コマンドです。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回は、連載第379回に続き、シェルスクリプト内などでオプションを解析する「getopt」コマンドです。
「getopt」は、シェルスクリプト内などでオプションを解析するコマンドです。自作のシェルスクリプトで「-a」のような「ハイフン+アルファベット1文字」のオプションを扱う際に便利です。「-f ファイル名」のように引数を取るオプションも解析できます。
よく似た名前で用途も同じ「getopts」コマンドとはどこが異なるのでしょうか(連載第378回)。まず、getoptsコマンドはbashのビルトインコマンドです。さらにgetoptsコマンドでは、「--」から始まるロングオプションを解析できません。
getoptコマンドは外部コマンド(/usr/bin/getopt)であり、ロングオプションの解析も可能です。
なお、getoptは、CentOS 8やUbuntu 18などに収録されているGNU版(util-linuxパッケージ収録、※1)の他に、macOSなどに収録されているBSD版が存在します。BSD版のgetoptは空白や特殊記号を含む引数をうまく扱えないという問題があるので注意してください(※2)。getoptコマンド以外の手段を検討した方がよいかもしれません。以下の解説はGNU版(CentOS 8版)のgetoptコマンドを使用しています。
※1 どの版を利用しているのかを調べるには「getopt --verion」を実行する。
※2 BSD版のmanには、この問題の解決が難しいことを次のように記している。「Arguments containing white space or embedded shell metacharacters generally will not survive intact; this looks easy to fix but isn't. People trying to fix getopt or the example in this manpage should check the history of this file in FreeBSD.」
この他、オプションを解析する際には、引数を1つずらす「shift」コマンドを使うことも可能です。
getopt [オプション] オプション文字列 引数
getopt [オプション] -o オプション文字列 -- 引数
getopt [オプション] -o オプション文字列 -l 長いオプション -- 引数
※ [ ]は省略可能な引数を示しています。
短いオプション | 長いオプション | 意味 |
---|---|---|
-o オプション | --options オプション | オプションとして使用したい文字を指定する(本文を参照) |
-l オプション | --longoptions オプション | 長いオプションとして使用したい文字列を指定する(-oと併用、複数ある場合は「,」で区切るか「-l」オプションを複数回使用する、本文を参照) |
-a | --alternative | 単一の「-」で始まるロングオプションを許可する |
-s シェルの種類 | --shell シェルの種類 | 使用するシェルを「sh」「bash」「csh」「tcsh」から指定する(デフォルトはbash、※3) |
-n | --name 名前 | getoptを使うプログラムの名前を指定する(エラーメッセージを表示する際に使用する) |
-q | --quiet | エラーメッセージを表示しない |
-Q | --quiet-output | 通常の出力を省略する |
-u | --unquoted | 出力にクオートを付けない |
※3 シェルによってエスケープの処理が異なるため、bash(デフォルト)以外のシェルスクリプトでgetoptコマンドを使用する場合に指定する。なお、zshの場合、「zparseopts」コマンド(man zshmodules参照)で長いオプションを解析可能。
getoptコマンドを使って長いオプション(ロングオプション)を解析したい場合は、「getopt -o オプション文字列 -l 長いオプション文字列 -- 引数」のようにします(画面1)。引数の部分に解析したい文字列を置きます。長いオプションが複数ある場合は「,」記号で区切るか、「-l」を複数回使用します。
「-o」は短いオプション用です(連載第379回)。短いオプションが不要の場合は「-o ""」のようにします(※4)。
※4 「-o」を使わない場合、「getopt -l 長いオプション文字列 "" -- 引数」のように、最後(-lなどのオプション指定の後)に「""」を指定する必要がある。
なお、長いオプションを使う際、「省略表記」に対応しています。例えば、「--file」「--quiet」「--quote」の3つが設定されている場合、「--f」で「--file」と見なし、「--qui」で「--quiet」と見なします。
getopt -o abc -l aaa,bbb -- 解析したい文字列
(短いオプション「-a」「-b」「-c」、長いオプション「--aaa」「--bbb」を使う場合を解析する)
getopt -o "" -l aaa,bbb -- 解析したい文字列
(短いオプションなし、長いオプション「--aaa」「--bbb」を使う場合を解析する)
長いオプションは「--file」のようにハイフンを2つ使います。しかしgetoptコマンドで解析する際、「-file」のようにハイフンが1つであっても許容したい、という場合は「-a」オプションを使用します。
getopt -a -o abc -l aaa,bbb -- 解析したい文字列
(短いオプションとして「-a」「-b」「-c」、長いオプション「--aaa」「-aaa」「--bbb」「-bbb」を使う場合を解析する)
getopt -a -o "" -l aaa,bbb -- 解析したい文字列
(短いオプションなし、長いオプション「--aaa」「-aaa」「--bbb」「-bbb」を使う場合を解析する)
画面2では、「-a」を指定した場合と指定しなかった場合の結果の違いを比較しています。
長いオプションを引数付きにしたい場合、オプションの後ろに「:」を付けます。例えば、「-l aaa,bbb,ccc」を解析する際、「aaa」と「ccc」を引数付きにするのであれば「-l aaa:,bbb,ccc:」のようにします(画面3)。
引数が必須ではない場合、つまりあってもなくてもよいという場合は「::」とします。
長いオプションに対する引数は、「--file=ファイル名」のように「=」を付けて指定しますが、「=」を省略して「--file ファイル名」のようにすることもあります。getoptコマンドではどちらの指定方法も利用できます(※5)。
※5 man getoptには次のように記述されている。「If the option has a required argument, it may be written directly after the long option name, separated by '=', or as the next argument (i.e. separated by whitespace on the command line).」
getopt -o "" -l aaa:,bbb,ccc: -- 解析したい文字列
(短いオプションなし、引数が必須の長いオプション「--aaa」、引数がない「--bbb」、引数が必須の「-ccc」を使う場合を解析する)
getopt -o "" -l aaa::,bbb,ccc: -- 解析したい文字列
(短いオプションなし、引数があってもなくてもよい長いオプション「--aaa」、引数がない「--bbb」、引数が必須の「-ccc」を使う場合を解析する)
引数が必須ではない場合、オプションに対する引数の指定方法によって解析結果が変わります。
「--file ファイル名」のようにオプションとスペースで区切った場合はオプションへの引数ではなく、コマンドライン全体の引数として解釈されます。getoptで解析した結果の順番が変わることに注意してください(画面4)。
getoptコマンドの出力を加工することで、より分かりやすくオプションや引数の解析結果を表示できます。ここでは長いオプションを扱った例を紹介します。
Copyright © ITmedia, Inc. All Rights Reserved.