名前

getopt - コマンドのオプションを解析する (強化版)

書式

getopt optstring parameters

getopt [options] [--] optstring parameters

getopt [options] -o|--options optstring [options] [--] parameters

説明

getopt は、コマンドラインのオプションを分解 (構文解析) して、シェル上の手続きによる解析作業を容易にしたり、 オプションが有効かどうかをチェックしたりするために使用する。 getopt は、そうしたことを行うのに GNU getopt(3) のルーティンを使っている。

getopt を呼び出すときに使用するパラメーターは、2 つの部分に分けることができる。 すなわち、getopt が解析を行うときの動作を変更するオプション部分 (上記「書式」の optionsopstring) と、解析の対象になるパラメーター部分 (上記「書式」の parameters) の 2 つである。2 番目の部分は、 オプションではない最初のパラメーターで、オプションの引数でもないものから始まるか、 あるいは、'--' が最初に現れた位置の直後から始まる。なお、1 番目の部分に '-o' や '--options' オプションが存在しない場合は、 2 番目の部分の最初のパラメーターが、 解析の対象となるショートオプションを 1 つにまとめたショートオプション文字列 (すなわち optsting) として使用される。

環境変数 GETOPT_COMPATIBLE が設定されている場合や、最初のパラメーターがオプションではない場合 ('-' で始まっていない場合であり、「書式」セクションの第 1 の書式)、この getopt は他のバージョンの getopt(1) と互換性のある出力を生成する。 なお、その場合でもやはりパラメーターの並べ替えは行うし、指定が任意の引数の認識もする (詳細については、「互換性」セクションを参照のこと)。

従来の getopt(1) の実装では、引数などのオプションではないパラメーターの中に、ホワイトスペースや (シェル固有の) 特殊文字などがあると、 それに対処することができなかった。 この問題を解決するために、この実装では、クォートした出力を生成できるようになっているが、 そうした出力は、シェルによってもう一度解釈される必要がある (たいていは、そのために eval コマンドを使用する)。 この出力形式を使えば、ホワイトスペースや特殊文字を保護することにはなるが、それには getopt を他のバージョンともはや互換性のない形で呼び出さなければならない (すなわち、「書式」セクションの第 2 や 第 3 の書式だ)。御使用のシステムに getopt(1) のこの強化版がインストールされているかどうかを知るには、 専用のテストオプション (-T) を使用すればよい。

オプション

-a, --alternative

ロングオプションを 1 個の '-' で始めることができるようにする。

-l, --longoptions longopts

認識すべきロングオプション (複数の文字からなる) を指定する。 2 個以上のオプション名を、カンマで区切って一度に指定することができる。 このオプションは複数回指定することもでき、その場合も longopts が追加されていく。 longouts 中の各ロングオプション名の後ろには、コロンを続けることができる。 コロンが 1 個のときは、 引数が必須だということであり、2 個のときは、 引数は任意、すなわち、あってもなくてもよいということである。

-n, --name progname

getopt(3) ルーティンが、エラーを通知する際に使用するプログラム名を指定する。 getopt(1) のエラーも、やはり getopt コマンドから発生するエラーとして報告されることに注意すること。

-o, --options shortopts

認識すべきショート (1 文字からなる) オプション群を指定する。 このオプションが指定されていない場合は、'-' で始まらない (そして、オプションの引数でもない) getopt の最初のパラメーターが、 ショートオプションを一つにまとめたショートオプション文字列として使用される。 shortopts 中のショートオプション各文字の後ろには、コロンを続けることができる。コロンが 1 個のときは、引数が必須だということであり、2 個のときは、引数は任意、すなわち、あってもなくてもよいということである。 また、shortopts の先頭に '+' や '-' という文字を付ければ、オプションの解析の仕方や、出力の生成の仕方を変更することができる (詳細については、「スキャンモード」セクションを参照すること)。

-q, --quiet

getopt(3) の出すエラーメッセージを表示しない。

-Q, --quiet-output

通常の出力を生成しない。 それでも、 -q を同時に指定しないかぎり、 getopt(3) によるエラー報告は行われる。

-s, --shell shell

クォート方式を shell のものにする。 -s オプションが指定されていない場合は、 BASH のクォート方式が使われる。 指定可能な引数は、現在のところ 'sh', 'bash', 'csh', 'tcsh' である。

-T, --test

現在使っている getopt(1) が、強化バージョンか古いバージョンかをテストする。 このオプションは何も出力しないが、エラーステータスを 4 にする。 getopt(1) の他の実装や、このバージョンでも環境変数 GETOPT_COMPATIBLE が設定されている場合は、 '--' を返して、エラーステータスを 0 にする。

-u, --unquoted

出力をクォートしない。 このモードでは、ホワイトスペースや (シェル依存の) 特殊文字が、混乱を引き起こすかもしれない点に注意すること (別の getopt(1) 実装でも同様)。

-h, --help

ヘルプを表示して終了する。

-V, --version

バージョンを表示して終了する。

構文解析

このセクションは、getopt のパラメーターの 2 番目の部分 (「書式」セクションの parameters) の書式について詳述している。 次のセクション (「出力」) では、生成される出力について説明する。一般に getopt は、シェル関数やシェルスクリプトの中で、その引数を解析するために使うものなので、 ここで取り上げるパラメーター群が、元はと言えば、 シェル関数を呼んだときに渡したパラメーターだったというのは、ごく普通のことである。 そこで、気を付けなければならないことがある。シェル関数を呼んだときに渡す各パラメーターは、 getopt に渡されるパラメーターリスト中のパラメーターと 1 対 1 で対応していなければならないのだ (「」セクションを参照)。 すべての解析は、GNU getopt(3) のルーティンによって行われる。

パラメーター群は左から右へ解析される。各パラメーターは、ショートオプション、ロングオプション、 オプションの引数、オプションとは無関係なパラメーターに分割分類される。

単純なショートオプションは、1 個の '-' に 1 個のショートオプション文字が続くものである。 オプションが引数を必須にしている場合は、オプション文字の直後に続けてもよく、 次のパラメーターとして (すなわち、コマンドライン上でホワイトスペースを間に置いて) 書いてもよい。オプションの引数が任意の場合は、それが存在するなら、 オプション文字の直後に続けなければならない。

1 個の '-' の後ろに数個のショートオプションをまとめて指定することもできる。 ただし、最後のオプション以外のすべてのオプションが、 必須や任意の引数を取らないという条件がある (例外として、最後のオプションは引数を取ることができる)。

ロングオプションは、通常 '--' で始まり、ロングオプション名がそれに続く。 オプションが引数を必須にしている場合は、ロングオプション名の直後に '=' で区切って続けてもよく、次の引数として (すなわち、コマンドライン上でホワイトスペースを間に置いて) 書いてもよい。 オプションの引数が任意の場合は、それが存在するなら、ロングオプション名の直後に '=' で区切って続けなければならない ('=' を続けたものの、その後に何も指定しない場合は、引数が存在しないかのように解釈される。 これはちょっとしたバグである。「バグ」セクションを参照)。 ロングオプションは、短縮しても他のオプションと区別が付くかぎり、短縮できる。

'-' で始まっていないパラメーターで、直前のオプションの必須の引数でもないものは、 いずれもオプションとは無関係なパラメーターである。 また、'--' というパラメーターの後にあるパラメーターは、 常にオプションとは無関係なパラメーターと解釈される。 環境変数 POSIXLY_CORRECT が設定されている場合や、ショートオプション文字列が '+' で始まっている場合は、オプションとは無関係な最初のパラメーターが見つかった時点で、 残りのすべてのパラメーターは、オプションとは無関係なパラメーターと解釈される。

出力

出力は、前のセクションで述べた要素のひとつひとつに対して生成される。 出力される順番は、オプションとは無関係なパラメーター以外は、 各要素が入力で指定された順番と同じである。出力は、互換 モード (クォートしないモード) で行うこともできるし、ホワイトスペースなどの特殊文字が、 オプション引数やオプションとは無関係なパラメーター中にある場合に、 そうしたものを保護する形で行うこともできる (「クォート」セクションを参照)。 出力はシェルスクリプト中で処理される際に、出力を構成する各要素が、 それぞれ他と区別されるものとして見えることになるので、(ほとんどのシェル言語で shift コマンドを使って) ひとつひとつ処理することが可能になる。 ただし、クォートなしのモードでのこの処理は、完全ではない。 要素にホワイトスペースや特殊文字が含まれていると、 思いがけないところで要素が分割されてしまうかもしれないのである。

たとえば、引数が必須なのに存在しないとか、未知のオプションがあるとかいう理由で、 パラメーターの解析中に問題が起きたときは、エラーメッセージが標準エラーに表示され、 問題を起こした要素については、何も出力されない。 そして、ゼロ以外のエラーステータスが返される。

ショートオプションに対しては、1 個の '-' とオプション文字が、ひとつのパラメーターとして生成される。 オプションに引数がある場合は、次のパラメーターはその引数である。 オプションの引数が任意なとき、その引数が見つからなかった場合は、 クォーティングモードでは、次のパラメーターが生成されるが、空のパラメーターになる。 クォートなしのモード (互換モード) では、2 番目のパラメーターは生成されない。 なお、getopt(1) の他の実装では、任意の引数をサポートしていないことが多い。

1 個の '-' の後ろに複数のショートオプションが指定されている場合は、 各オプションがそれぞれ独立したパラメーターとして出力されることになる。

ロングオプションに対しては、'--' と省略なしのオプション名がひとつのパラメーターとして生成される。 この動作は、入力中でオプションが短縮されているかどうかや、1 個の '-' とともに指定されているかどうかとは、関係がない。 引数の処理は、ショートオプションの場合と同じである。

通常、オプションとは無関係なパラメーターの出力が生成されるのは、 すべてのオプションとその引数が生成されてからである。 それから、'--' が 1 個のパラメーターとして生成され、 その後で、オプションとは無関係なパラメーターが、 見つかった順序で、それぞれ独立したパラメーターとして生成される。 ただし、ショートオプション文字列の最初の文字が '-' のときだけは別で、その場合は、オプションとは無関係なパラメーターの出力は、 入力中のそれが見つかった位置で生成される (この動作は、「書式」セクションの第 1 の書式が使用されている場合には、サポートされない。 その場合は、ショートオプション文字列の前にある '-' や '+' は、すべて無視される)。

クォート

互換モードでは、オプションの引数やオプションとは無関係なパラメーター中に、 ホワイトスペースや特殊文字があると、それを適切に処理できない。 そのため、互換モードの出力を渡されたシェルスクリプトは、 その出力をどのように個々のパラメーターに分割することが期待されているのか、わからないことになる。 この問題を回避するために、getopt のこの実装では、クォートによる保護を提供している。 要するに、出力を生成するとき、パラメーターをひとつひとつ引用符で囲んでやるのである。この出力を (たいていは、シェルの eval コマンドを使って) もう一度シェルに渡してやれば、別々のパラメーターに適切に分割されることになる。

次の場合には、引用符による保護が行われない。環境変数 GETOPT_COMPATIBLE が設定されている場合、「書式」セクションの第 1 の書式が使われている場合、'-u' オプションが指定されている場合。

クォート方式はシェルごとに異なる。自分が使用しているシェルの方式を選ぶには、'-s' オプションを使えばよい。 現在サポートしているシェルは、'sh', 'bash', 'csh', 'tcsh' である。 実のところ、sh 風のクォート方式と csh 風のクォート方式という、2 つの系統しか区別していない。 別のシェルスクリプト言語を使用している場合でも、この 2 つの系統のどちらかが多分使えるだろう。

スキャンモード

ショートオプション文字列の先頭には、1 個の '-' または '+' を付けて、特別なスキャンモードを指示することができる。 「書式」セクションの第 1 の呼び出し形式が使用されている場合には、 こうしたプラスやマイナス記号は無視されるが、そのときでも、環境変数 POSIXLY_CORRECT が設定されているかどうかは確認される。

先頭文字が '+' の場合や、環境変数 POSIXLY_CORRECT が設定されている場合は、オプションではないパラメーターで (すなわち、'-' で始まっていないパラメーターで)、かつオプションの引数でもないものが最初に見つかった時点で、 解析はストップする。 残りのパラメーターはすべて、オプションとは無関係なパラメータと見なされる。

先頭文字が '-' の場合、オプションとは無関係なパラメーターは、 それが見つかった位置に出力される。それに対して、通常の動作では、 そうしたパラメーターは、1 個の '--' というパラメーターが生成された後で、 出力の末尾に全部まとめて置かれるのである。 なお、このモードでも、'--' というパラメーターはやはり生成されるが、必ず最後のパラメーターになる。

互換性

このバージョンの getopt(1) は、できるだけ他のバージョンと互換性があるように書かれている。 たいていの場合、他のバージョンの getopt をこのバージョンで置き換えるだけでよく、 既存のシェルスクリプトなどに手を入れる必要はない。さらに、いくつかの利点もある。

getopt の最初のパラメーターの最初の文字が '-' でない場合、getopt は互換モードになる。 最初のパラメーターは、ショートオプションをひとつにまとめた文字列と見なされ、 他のすべての引数は、解析の対象になる。 この場合でも、環境変数 POSIXLY_CORRECT が設定されていないかぎり、パラメーターの並べ替えは行う。 (すなわち、オプションとは無関係なすべてのパラメーターは、最後に出力される)。その場合には getopt が、 ショートオプションの先頭に自動的に '+' を付与する。

環境変数 GETOPT_COMPATIBLEgetopt を強制的に互換モードにする。この環境変数と POSIXLY_CORRECT の両方を設定すると、「気難しい」プログラムのために 100% の互換性が得られる。 しかし、通常はどちらも設定する必要はない。

互換モードでは、 ショートオプションの文字列先頭に付く '-' や '+' は無視される。

返り値

getopt は、解析に成功した場合は、エラーコード 0 を返す。 getopt(3) がエラーを返した場合は 1 を返す。 自分自身に対して与えられたパラメーターが理解できなかった場合は 2 を返す。メモリが足りない (out-of-memory) といった内部エラーが起きた場合は 3 を返す。-T オプションを付けて呼び出された場合は 4 を返す。

getopt(1) の配布では、(ba)sh と (t)csh 用のスクリプトの見本を提供している。インストール場所は /usr/share/doc/util-linux/ である。

環境変数

POSIXLY_CORRECT

この環境変数は getopt(3) ルーティンによって調べられる。これが設定されている場合、 オプションでもオプションの引数でもないパラメーターが見つかった時点で、解析は停止する。 それ以降のすべてのパラメーターは、'-' で始まっているかどうかに関係なく、オプションとは無関係なパラメーターとして解釈される。

GETOPT_COMPATIBLE

getopt に対して強制的に「書式」セクションの第 1 の呼び出し形式を使わせる。

バグ

getopt(3) 関数は、引数が任意のロングオプションが空の任意引数を渡された場合、それを解析できる (だが、ショートオプションに対しては、それができない)。一方、この getopt(1) コマンドは、空の任意引数を、引数が存在しないかのように処理している。

ショートオプションを全く使いたくない場合の getopt コマンドの構文は、あまり直感的ではない (ショートオプション文字列を明示的に空文字列にしなければならないのだ)。

作者

関連項目

bash(1), tcsh(1), getopt(3)

バグ報告

バグ報告は、 以下にある issue トラッカーを利用すること。 <https://github.com/util-linux/util-linux/issues>.

入手方法

getopt コマンドは util-linux パッケージの一部であり、 以下からダウンロードできる。 Linux Kernel Archive <https://www.kernel.org/pub/linux/utils/util-linux/>.