Getopt は、 Unix/POSIX スタイルのコマンドライン オプションを解析するために使用されるC ライブラリ 関数です。これはPOSIX仕様の一部であり、Unix 系システムに共通です。また、シェル スクリプトのコマンドライン引数を解析するための Unix プログラムの名前でもあります。
歴史
コマンドライン プログラムの長年の課題は、オプションの指定方法でした。初期のプログラムでは、単一文字オプション ( -a)、複数のオプションを一緒に指定する (-abcは と同等-a -b -c)、複数文字オプション ( -inum)、引数付きオプション ( -a arg、-inum 3、-a=arg)、異なるプレフィックス文字 ( -a、+b、/c) など、さまざまな方法が使用されていました。
getopt関数は、すべてのプログラムがコマンドライン オプションを解析するために使用できる標準メカニズムとして作成され、誰もが依存 できる共通のインターフェイスが実現されました。そのため、元の作者は、オプション文字列によって制御可能な、単一文字オプション、一緒に指定された複数のオプション、および引数 (または) を持つオプションのサポートというバリエーションを選択しました。
-a arg-aarg
getoptの歴史は少なくとも 1980 年まで遡り[1] 、1985 年にテキサス州ダラスで開催された UNIFORUM カンファレンスでAT&Tが初めて公開しました。当初はパブリック ドメインで利用できるようにする意図がありました。[2]その後、そのバージョンは他の Unix 系 OS ( 4.3BSD、Linuxなど)にも採用されました。POSIX.2標準ではunistd.h ヘッダー ファイルの一部として指定されています。多くのプログラミング言語でコマンドライン オプションを解析するために、 getoptの派生版が作成されています。
getopt[3]のPOSIX標準の関連関数はであるgetsubopt。[4]これはコンマで区切られたサブオプションの文字列を解析する。4.4BSD(1995)で登場した。[5]
拡張機能
getoptはシステム依存の関数であり、その動作はCライブラリの実装に依存します。ただし、 gnulibのようなカスタム実装も利用可能です。[6]
従来の(POSIX および BSD)処理では、最初の非オプション引数に遭遇するとオプションが終了し、getopt はそれを通知するために -1 を返します。ただし、 glibc拡張では、使いやすさのためにオプションはどこでも許可されます。getoptは暗黙的に引数ベクトルを並べ替えるため、最後には非オプションが残ります。POSIX にはすでに -1 を返してスキップするという慣例があるため、これをオプションの終了を示すものとして常に移植可能に使用できます。[6]--
GNU拡張のgetopt_long は、1 つのダッシュではなく 2 つのダッシュで始まる、より読みやすい複数文字のオプションの解析を可能にします。2 つのダッシュを選択することで、複数文字のオプション ( ) を一緒に指定された 1 文字のオプション ( ) と区別できます。GNU 拡張では、引数を持つオプションの代替形式も許可されます: 。[6]このインターフェイスは人気があり、 FreeBSDやSolaris を含む多くの BSD ディストリビューションで (順列なしで) 採用されています。[7]長いオプションをサポートする別の方法は、Solaris とKorn Shell ( optstring の拡張) で見られますが、それほど人気がありませんでした。[8]--inum-abc--name=arg
getopt のもう 1 つの一般的な高度な拡張機能は、引数の解析状態をリセットすることです。これは、options-anyware GNU 拡張機能の代替として、またはさまざまなレベルでさまざまなオプションを持つコマンドライン インターフェイスのセットを「レイヤー化」する方法として役立ちます。これは、BSD システムではoptreset変数を使用して、GNU システムではoptind を0 に設定することで実現されます。[6]
使用法
ユーザー向け
getoptベースのプログラムのコマンドライン構文はPOSIX推奨のユーティリティ引数構文です。簡単に言うと[9]
-オプションは、先頭に(ハイフンとマイナス) 文字が付いた 1 文字の英数字です。- オプションには、必須またはオプションの引数、あるいは引数なしを指定できます。
- オプションが引数を取ることを指定するには、
:オプション名の後に含めます(初期指定時のみ) - オプションが引数を取る場合、これは同じトークン内または次のトークン内にあります。つまり、 が
o引数を取る場合、-ofooは と同じです-o foo。 - 最後以外のオプションが引数を取らない限り、複数のオプションを連結できます。
aと が引数を取らず、 がオプションの引数bを取る場合、は と同じですが、前述の規則によりと同じではありません。e-abe-a -b -e-bea-b -e a - すべてのオプションは、非オプション引数の前にあります (GNU 拡張を除く)。
--は常にオプションの終わりを示します。
構文の拡張にはGNU規約とSunのCLIP仕様が含まれる。[10] [11]
プログラマー向け
GNUのgetoptマニュアルではgetoptの使い方を次のように規定している: [12]
#include <unistd.h>
int getopt ( int argc , char * const argv [], const char * optstring );
ここで、argcとargv は、C のメイン関数プロトタイプとまったく同じように定義されています。つまり、argc は argv 文字列配列の長さを示します。optstring には、検索するオプション ( W を除く通常の英数字) と、引数を受け入れるオプション (コロン) の指定が含まれています。たとえば、「vf::o:」は、引数なしのv、オプション引数のf、および必須引数のoの 3 つのオプションを指します。GNU はここで、長いオプション同義語用のW拡張を実装しています。 [12]
getopt自体はオプション文字またはオプション終了の場合は-1の整数を返します。[12]この慣用句は、whileループを使用してオプションを調べ、switch-case文を使用してオプションを選択して操作することです。この記事の例のセクションを参照してください。
プログラムに追加情報を伝達するために、externプログラムはいくつかのグローバル変数を参照して情報を取得しますgetopt。
extern char * optarg ; extern int optind 、opterr 、optopt ;
- オプタルグ
- 現在のオプションの引数へのポインター(存在する場合)。解析を(再度)開始する場所を制御するために使用できます。
- オプトイン
- getopt が現在argv内で参照している場所。
- オプテア
- getopt がエラー メッセージを出力するかどうかを制御するブール スイッチ。
- オプション
- 認識されないオプションが発生した場合、その認識されない文字の値。
GNU 拡張getopt_longインターフェースも同様ですが、別のヘッダー ファイルに属し、長いオプションの「短い」名前といくつかの追加の制御を定義するための追加のオプションを取ります。短い名前が定義されていない場合、getopt は代わりにオプション構造を参照するインデックスをlongindexポインタに配置します。[12]
#include <getopt.h>
int getopt_long ( int argc 、char * const argv []、const char * optstring 、const struct option * longopts 、int * longindex );
例
POSIX標準の使用取得
#include <stdio.h> /* printf 用 */ #include <stdlib.h> /* exit 用 */ #include <unistd.h> /* getopt 用 */ int main ( int argc , char ** argv ) { int c ; int digit_optind = 0 ; int aopt = 0 , bopt = 0 ; char * copt = 0 , * dopt = 0 ; while (( c = getopt ( argc , argv , "abc:d:012" )) != -1 ) { int this_option_optind = optind ? optind : 1 ; switch ( c ) { case '0' : case '1' : case '2' : if ( digit_optind != 0 && digit_optind != this_option_optind ) { printf ( "数字が 2 つの異なる argv 要素に出現しています。\n " ); } digit_optind = this_option_optind ; printf ( "オプション %c \n " , c ); break ; case 'a' : printf ( "オプション a \n " ); aopt = 1 ; break ; case 'b' : printf ( "オプション b \n " ); bopt = 1 ; break ; case 'c' : printf ( "値 '%s' のオプション c \n " , optarg ); copt = optarg ; break ; case 'd' :printf ( "値 '%s' のオプション d \n " , optarg );
dopt = optarg ; break ; case '?' : break ; default : printf ( "?? getopt が文字コード 0%o を返しました ?? \n " , c ); } } if ( optind < argc ) { printf ( "非オプション ARGV 要素: " ); while ( optind < argc ) { printf ( "%s " , argv [ optind ++ ]); } printf ( " \n " ); } exit ( 0 ); }
GNU拡張機能の使用getopt_long
#include <stdio.h> /* printf 用 */ #include <stdlib.h> /* exit 用 */ #include <getopt.h> /* getopt_long 用; POSIX 標準の getopt は unistd.h にあります */ int main ( int argc , char ** argv ) { int c ; int digit_optind = 0 ; int aopt = 0 , bopt = 0 ; char * copt = 0 , * dopt = 0 ; static struct option long_options [] = { /* NAME ARGUMENT FLAG SHORTNAME */ { "add" , required_argument , NULL , 0 }, { "append" , no_argument , NULL , 0 }, { "delete" , required_argument , NULL , 0 }, { "verbose" , no_argument , NULL , 0 }, { "create" , required_argument , NULL , 'c' }, { "file" , required_argument , NULL , 0 }, { NULL , 0 , NULL , 0 } }; int option_index = 0 ; while (( c = getopt_long ( argc , argv , "abc:d:012" , long_options , & option_index )) != -1 ) { int this_option_optind = optind ? optind : 1 ; switch ( c ) { case 0 : printf ( "option %s" , long_options [ option_index ]. name );
if ( optarg ) { printf ( " 引数 %s 付き " , optarg ); } printf ( " \n " ); break ; case '0' : case '1' : case '2' : if ( digit_optind != 0 && digit_optind != this_option_optind ) { printf ( "数字は 2 つの異なる argv 要素に出現します。\n " ); } digit_optind = this_option_optind ; printf ( "オプション %c \n " , c ); break ; case 'a' : printf ( "オプション a \n " ); aopt = 1 ; break ; case 'b' : printf ( "オプション b \n " ); bopt = 1 ; break ; case 'c' : printf ( "オプション c、値 '%s' \n " , optarg ); copt = optarg ; break ; case 'd' : printf ( "オプション d、値 '%s' \n " , optarg ); dopt = optarg ; break ; case '?' : break ; default : printf ( "?? getopt が文字コード 0%o を返しました ?? \n " , c ); } } if ( optind < argc ) { printf ( "非オプション ARGV 要素: " ); while ( optind < argc ) { printf ( "%s " ,argv [ optind ++ ]); } printf ( " \n " ); }終了
(0 );
}
シェル内
シェル スクリプト プログラマーは、一般的に、オプションを提供するための一貫した方法を提供したいと考えています。この目標を達成するために、彼らは getopts を利用して、それを独自の言語に移植しようとします。
最初の移植の試みは、 Unix System Laboratories (USL)によって実装されたプログラムgetoptでした。このバージョンでは引用符やシェルのメタ文字を処理できず、引用符の試みが見られませんでした。これは FreeBSD に継承されました。[13]
1986 年、USL はメタ文字と空白文字の周囲で安全でないことはもはや許容されないと判断し、代わりに Unix SVR3 Bourne Shell 用の組み込みgetoptsコマンドを作成しました。シェルにコマンドを組み込む利点は、シェルの変数にアクセスできるようになり、値を引用符で囲むことなく安全に書き込むことができることです。このコマンドは、シェル独自の変数を使用して、現在の位置と引数の位置 ( OPTINDとOPTARG )を追跡し、オプション名をシェル変数に返します。
1995年に、Single UNIX仕様バージョン1 / X/Open移植性ガイドライン第4版getoptsに含まれました。[14]現在ではPOSIXシェル標準の一部となっているgetoptsは、POSIX準拠を目指す他の多くのシェルにも広く普及しています。
getopt は、util-linux が拡張バージョンをリリースするまで、基本的に忘れ去られていました。このバージョンでは、エスケープによって古い getopt の問題がすべて修正されました。また、GNU の長いオプション名もサポートされています。 [15]一方、長いオプションはgetopts他のシェルのコマンドではほとんど実装されておらず、ksh93は例外です。
他の言語
getopt は、一般的な POSIX コマンド引数構造の簡潔な記述であり、コマンドライン上のユーザーと自分自身の両方に同様のインターフェイスを提供しようとしているプログラマーによって広く複製されています。
getoptC: POSIX以外のシステムにはCライブラリは同梱されていませんが、 gnulib [6]とMinGW (どちらもGNUスタイルを受け入れます)、およびいくつかのより最小限のライブラリを使用して機能を提供することができます。[16]代替インターフェースも存在します。- RPM パッケージ マネージャー
poptによって使用されるライブラリには、再入可能という追加の利点があります。 - glibc と gnulib の関数ファミリ
argpは、さらなる利便性とモジュール性を提供します。
- RPM パッケージ マネージャー
- D プログラミング言語: D 標準ライブラリに getopt モジュールがあります。
- Goには長いフラグ名を許可する
flagパッケージ[17]が付属しています。getoptパッケージ[18]getoptはC関数に近い処理をサポートします。オリジナルのPOSIXのものに非常に近いインターフェースを提供する別のパッケージ[19]もあります。 - Haskell : System.Console.GetOptが付属しており、これは基本的にGNU getoptライブラリのHaskellポートです。[20]
- Java : Java標準ライブラリにはgetoptの実装はありません。GNU getoptから移植されたgnu.getopt.Getopt [21]やApache Commons CLI [22]など、いくつかのオープンソースモジュールが存在します。
- Lisp : 共通の標準ライブラリのないさまざまな方言があります。Lisp の一部の方言には、getopt のサードパーティ実装がいくつかあります。Common Lisp には、著名なサードパーティ実装があります。
- Free Pascal : GetOpts という標準ユニットの 1 つとして独自の実装があります。すべてのプラットフォームでサポートされています。
- Perlプログラミング言語: 標準ライブラリには、Getoptの2つの派生クラス、Getopt::Long [23]とGetopt::Std. [24]があります。
- PHP :getopt関数がある。[25]
- Python :標準ライブラリにCのgetoptとGNU拡張に基づいたモジュールが含まれています。 [26] Pythonの標準ライブラリには、より便利に使用できるオプションを解析するための他のモジュールも含まれています。[27] [28]
- Ruby : 標準ライブラリ GetoptLong に getopt_long の実装があります。Ruby の標準ライブラリには、より洗練された便利なインターフェースを備えたモジュールもあります。オリジナルの getopt インターフェースのサードパーティ実装も利用可能です。
- .NET Framework : 標準ライブラリにgetopt機能はありません。サードパーティの実装が利用可能です。[29]
参考文献
- ^ "usr/src/lib/libc/pdp11/gen/getopt.c". System IIIより、1980年6月リリース。Warren ToomeyのThe Unix Treeプロジェクトからリンクされています。2023年5月12日時点のオリジナルよりアーカイブ。 2024年4月22日閲覧。
{{cite web}}: CS1 maint: others (link) - ^ Quarterman, John (1985-11-03). 「パブリック ドメイン AT&T getopt ソース」. linux.co.cr (mod.std.unix ニュースグループに最初に掲載) . 2023-05-12 時点のオリジナルよりアーカイブ。2024-04-22に取得。
- ^ "getopt" (The Open Group Base Specifications Issue 7、2018年版、IEEE Std 1003.1-2017 (IEEE Std 1003.1-2008の改訂版) ed.) The Open Group . 2018年。2024年3月24日時点のオリジナルよりアーカイブ。 2024年4月22日閲覧。
- ^ "getsubopt" (The Open Group Base Specifications Issue 7、2018年版、IEEE Std 1003.1-2017 (IEEE Std 1003.1-2008の改訂版) ed.) The Open Group . 2018年。2023年12月2日時点のオリジナルよりアーカイブ。 2024年4月22日閲覧。
- ^ – FreeBSDライブラリ関数マニュアル
- ^ abcde "getopt". GNU Gnulib . 2020年1月23日閲覧。
- ^ – FreeBSDライブラリ関数マニュアル
- ^ "getopt(3)"。Oracle Solaris 11.2情報ライブラリ。
- ^ 「ユーティリティ規約」POSIX.1-2018。
- ^ 「引数構文」。GNU C ライブラリ。2020年1 月 24 日閲覧。
- ^ David-John, Burrowes; Kowalski III, Joseph E. (2003-01-22). 「CLIP 仕様、バージョン 1.0、PSARC 1999/645」(PDF)。2020-06-27 のオリジナル(PDF)からアーカイブ。
- ^ abcd – Linuxライブラリ関数マニュアル
- ^ – FreeBSD一般コマンドマニュアル
- ^ "getopts". The Open Group (POSIX 2018) .
- ^ – Linuxユーザーマニュアル– ユーザーコマンド
- ^ 「visual studio - getopt.h: Windows で Linux C コードをコンパイルする」。Stack Overflow。
- ^ 「パッケージフラグ」。
- ^ 「パッケージgetopt」。
- ^ 「パッケージgetopt」。
- ^ 「System.Console.GetOpt」。
- ^ 「クラス gnu.getopt.Getopt」 。2013年 6 月 24 日閲覧。
- ^ 「Commons CLI」。Apache Commons。Apache Software Foundation。2013 年 2 月 27 日。2013年6 月 24 日閲覧。
- ^ "Getopt::Long - perldoc.perl.org".
- ^ "Getopt::Std - perldoc.perl.org".
- ^ 「PHP: getopt - マニュアル」.
- ^ 「16.5. getopt — コマンドラインオプション用の C スタイルパーサー — Python 3.6.0 ドキュメント」。
- ^ 「コマンドラインオプションのパーサー」。2013年4月30日閲覧。 バージョン 2.7 以降では非推奨
- ^ 「コマンドラインオプション、引数、サブコマンドのパーサー」。2013年4月30日閲覧。
- ^ 「GNU Getopt .NET」。GitHub。
外部リンク
- POSIX仕様
- GNU getopt マニュアル
- Unicode およびマルチバイト Microsoft Visual C、C++、または MFC プロジェクト用の完全な getopt ポート
