DOKK / manpages / debian 11 / manpages-ja / getopt.1.ja
GETOPT(1) User Commands GETOPT(1)

名前

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) として使用される (訳注: これは 2 番目の書式のことである)。

[訳注]
第 3 の書式で、解析の対象になるパラメータをオプションから始めるときは、その前に '--' を置かなければならないことに気を付けていただきたい。 そうしないと、getopt 自体のオプションと誤解されることになる。 解析の対象をファイル名などから始めるときは、'--' を置かなくてもよい。

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

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

オプション

ロングオプションを 1 個の '-' で始めることができるようにする。
ヘルプを表示して、終了する。それ以上何も出力しない。
認識すべきロング (複数の文字からなる) オプション群を指定する。 2 個以上のオプション名を、コンマで区切って一度に指定することができる。 このオプションは複数回指定することもでき、その場合も longopts が追加されていく。longouts 中の各ロングオプション名の後ろには、コロンを続けることができる。コロンが 1 個のときは、 引き数が必須だということであり、2 個のときは、 引き数は任意、すなわち、あってもなくてもよいということである。
getopt(3) ルーティンが、エラーを通知する際に使用するプログラム名を指定する。 getopt(1) 自体に関するエラーは (訳注: たとえば、 getopt コマンドのオプションが間違っている場合などは)、やはり getopt コマンドがエラーの発生元として報告されることに注意していただきたい。
認識すべきショート (1 文字からなる) オプション群を指定する。 このオプションが指定されていない場合は、'-' で始まらない (そして、オプションの引数でもない) getopt の最初のパラメータが、 ショートオプションを一つにまとめたショートオプションズ文字列として使用される (訳注: 「書式」セクションの第 2 の書式)。shortopts 中のショートオプション各文字の後ろには、コロンを続けることができる。コロンが 1 個のときは、引き数が必須だということであり、2 個のときは、引き数は任意、すなわち、あってもなくてもよいということである。 また、shortopts の最初の文字を '+' や '-' にすれば、オプションの解析や、出力の生成の仕方に影響を与えることができる (詳細については、「スキャニングモード」セクションを参照すること)。
getopt(3) の出すエラーメッセージを表示しない。
通常の出力を生成しない。それでも、 -q も同時に指定しないかぎり、 getopt(3) によるエラー報告は行われる。
クォート方式を shell のものにする。-s オプションが指定されていない場合は、 BASH のクォート方式が使われる。 指定可能な引き数は、現在のところ 'sh', 'bash', 'csh', 'tcsh' である。
現在使っている getopt(1) が、強化バージョンか古いバージョンかをテストする。 このオプションは何も出力しないが、エラーステータスを 4 にする。 getopt(1) の他の実装や、このバージョンでも環境変数 GETOPT_COMPATIBLE が設定されている場合は、 '--' を返して、エラーステータスを 0 にする。
出力をクォートしない。このモードでは、ホワイトスペースや (シェルによって様々な) 特殊文字が、 (getopt(1) の他の実装におけると同様に) 望ましからぬ混乱を引き起こしかねないことに、注意していただきたい。
バージョン情報を表示して、終了する。それ以上何も出力しない。

構文解析

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

[訳注]
getopt の使い方の簡単な例を挙げる。 たとえば、シェル関数やシェルスクリプト中に次のように書く。


PARAM=$(getopt -o 'a:b::c' -- "$@")
eval set -- "$PARAM"

このようにして、シェル関数やスクリプトに渡された引き数群を、位置パラメータを利用して、 どれがオプションで、どれがそのオプション引き数、どれがそれ以外か、 わかりやすいように、処理しやすいように再構成するわけである。 詳しくは、「出力」セクションや、 「用例」で述べているスクリプトの見本を参照していただきたい。

「シェル関数を呼んだときに渡す各パラメータは、getopt に渡されるパラメータリスト中のパラメータと 1 対 1 で対応するように、気を付けて指定しなければならない」というのは、 シェル関数やシェルスクリプトに渡すパラメータでも、 それが空白などを含むようならクォートしなければならないのはもちろん、以下で説明するような getopt コマンドのパラメータの書式にも従っていなければならないということである。 たとえば、引き数が任意のショートオプション -b に引き数を指定する場合は、-bXXX などと、間に空白を置かずに指定しなければならない。

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

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

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

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

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

出力

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

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

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

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

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

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

クォート

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

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

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

スキャニングモード

ショートオプションズ文字列 (訳注: 「書式」の optstring) の先頭には、1 個の '-' または '+' を付けて、特別なスキャニングモードを指示することができる。 「書式」の第 1 の呼び出し形式が使用されている場合には、 こうしたプラスやマイナス記号は無視されるが、そのときでも、環境変数 POSIXLY_CORRECT が設定されているかどうかは、やはり調べられる (訳注: 実際には、 第 1 の書式で optstring の先頭に '-' を付けると、2, 3 番目の書式と混同されて、多分エラーになる)。

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

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

互換性

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

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

環境変数 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/getopt//usr/share/doc/ 以下の util-linux のサブディレクトリにあるだろう。

環境変数

この環境変数は getopt(3) ルーティンによって調べられる。これが設定されている場合、 オプションでもオプションの引き数でもないパラメータが見つかった時点で、解析は停止する。 それ以降のすべてのパラメータは、'-' で始まっているかどうかに関係なく、オプションとは無関係なパラメータとして解釈される。
getopt に対して強制的に「書式」セクションの第 1 の呼び出し形式を使わせる。

バグ

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

[訳注]
詳しく言うと、getopt(3) (getopt_long(3)) 関数は、 引き数が任意のロングオプションに引数がない場合と、空の引き数を渡された場合とを区別している。 しかし、ショートオプションについては、その区別ができない。

この getopt(1) コマンドの動作について言うと、第 2、第 3 の書式では、ロングオプション、ショートオプションを問わず、 引き数が任意のオプションに引き数が存在しない場合も、引き数が空文字列である場合も、 オプションの引き数として空文字列を出力する。 また、第 1 の書式では、引き数が任意のオプションに引き数が存在しない場合も、 引き数が空文字列の場合も、そのオプションの引き数はまったく出力されない。 「出力」セクションのショートオプションの説明を参照していただきたい。

要するに、この getopt コマンドでは、引き数が任意のオプションについて、 引き数が存在しない場合と引き数が空文字列である場合の区別がまったくないのである。 だから、バグと言っても、不具合ということではなく、このコマンドと getopt(3) 関数の仕様が微妙に違うことを言っているのだろうと思う。

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

[訳注]
すなわち、getopt -o '' --longoptions ... のように使用しなければならない。

作者

Frodo Looijaard <frodo@frodo.looijaard.name>

関連項目

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

入手方法

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

December 2014 util-linux