Skip to content

Instantly share code, notes, and snippets.

@ryotako
Last active May 26, 2023 01:32
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryotako/de204fe4564cb3a76b48b247e6c68d42 to your computer and use it in GitHub Desktop.
Save ryotako/de204fe4564cb3a76b48b247e6c68d42 to your computer and use it in GitHub Desktop.
argparseの日本語訳(若干の意訳を含む)

argparse(1)

名称

argparse - argparse - fishのスクリプトや関数に渡されるオプションの解析

記述

このコマンドはfishのスクリプトや関数が,fishのビルトイン関数が引数を扱うのと100%同じ方法で引数を取り扱うのを簡単にします. ユーザは有効なオプションを定義する引数の組を渡し,リテラル--を続け,その後に解析される引数(リテラル--を含んでもよい)を渡します. これに関する詳細は以下の「使い方」の節で述べます.

OPTION_SPECは以下で述べるドメイン特化言語で記述されるか,fish_optコマンドによって生成されます. すべてのオプション指定はargparse自身のフラグの後,かつ解析すべき引数とオプション指定とを隔てる--の前に置く必要があります.

ARGのリストにオプションが現れると,それぞれについて_flag_Xという変数が作成されます.ここでXはショートフラグの文字やロングフラグの名前です. OPTION_SPECは,それが使われない場合にも常にショートフラグを要求します. そのため,ショートフラグあるいはロングフラグが使われたなら,ショートフラグの文字を用いた_flag_X変数が常に作成されます. ロングフラグ名の変数(たとえば_flag_help)はオプション指定がロングフラグ名を含む場合にのみ定義されます.

たとえば_flag_h_flag_helpは,-hあるいは--helpが使用された場合に見られます. これらの変数はローカルスコープに(すなわち,スクリプト中でset -l _flag_xが実行されたかのように)定義されます. もしフラグがブーリアンなら(つまり,オプション引数を取らないなら),変数の値はショートフラグやロングフラグそのものとなります. もしオプションがブーリアンでないなら,変数の値はARGリストの処理中に収集されたゼロ個以上の値となります. フラグが使われなかった場合には,フラグ変数は定義されません.

以下のargparseのオプションが利用可能です. これらはOPTION_SPECよりも前に指定される必要があります.

  • -nあるいは--nameはエラーメッセージ中に挿入されるコマンドの名前です.この値を指定しない場合はargparseが使用されます.
  • -xあるいは--exclusiveには,互いに排他的なショートオプションあるいはロングオプションのコンマ区切りのリストが続きます.ユーザは,互いに排他的なオプションの組を複数組定義するために,このオプションを複数回使用することができます.
  • -Nあるいは--min-argsには受け取れる非オプション引数の数の下限を示す整数を与えます.デフォルトはゼロです.
  • -Xあるいは--max-argsには受け取れる非オプション引数の数の上限を示す整数を与えます.デフォルトは無限大です.
  • -sあるいは--stop-nonoptを指定すると最初の非オプション引数に出会った時点で引数の走査が停止します.このフラグを使うことはCの関数getopt_long()+記号で始まるショートオプションで呼び出すことと等価です.この挙動はしばしば「POSIX的に正しい」と呼ばれます.このフラグが使用されない場合は引数は再配列(順序が変更)され,非オプション引数はオプション引数の後に移動されます.このモードにはいくつかの用途がありますが,主要な用途はサブコマンドを持つコマンドの実装です.
  • -hあるいは--helpはこのコマンドの使用法を表示します.

使い方

このコマンドを使う際には,--で区切られた二組の引数を渡します. 最初の組は一つか複数のオプション指定(上記のOPTION_SPEC)と,argparseの挙動を変更するためのオプションからなります. これらは--よりも前に列挙する必要があります. 第二の組はオプション仕様に従って解析される引数です. これらは--より後に置き,空でも構いません. 以下でこれについて詳細に説明しますが、ここではmy_functionという名前の関数で使用される簡単な例を示します.

argparse --name=my_function 'h/help' 'n/name:' -- $argv
or return

(訳注: 例の中の'n/name:'n/name=の誤りと思われます)

もし$argvが空なら解析するべきものはなく,argparseは成功を示すゼロを終了ステータスに返します. $argvが空でないなら,フラグ-h, --help, -n, --nameがチェックされます. それらのオプションが見つかったのなら,それらは引数から除かれ,ローカル変数(詳細は後で示す)が定義され,どのオプションが指定されたのかスクリプト中で判別することができます. $argvが,必須のオプション引数が指定されていない等のエラーを含まないなら,argparseは終了ステータスとしてゼロを返して終了します. そうでなければ,argparseは適切なエラーメッセージをstderrに書き出し,終了ステータスとして1を返して終了します.

引数に--を含まないのはエラーです. --の後に引数を置かないことはできますが,--は必須です. たとえば,以下は可能です.

set -l argv
argparse 'h/help' 'n/name' -- $argv

argparseの引数として最初に現れる--は,オプションの仕様とコマンドの引数とを確実に区別するためのものだからです.

オプションの仕様

各オプション仕様は以下の文字列からなります.

  • ショートフラグの文字(必須).これはアルファベット,数字,あるいは#です.#は特別で,-123のような形式のフラグが有効であることを意味します.ショートフラグ#-を続ける必要があり(_flag_#が無効な変数名なのでショートフラグ名が無効であるからです),修飾子を伴わないロングフラグ名を続ける必要があります.
  • コマンドの利用者にショートフラグの使用を認める場合は/を,ショートフラグを無効とする場合は-を使います.
  • ショートフラグ名とロングフラグ名を指定する際に#を使うこともできます.この方法は,値が整数であることが明示します.つまり,フラグは-NNNといった形式を取り得ます.
  • ロングフラグ名は省略可能です.ロングフラグ名が指定されなかった場合,ショートフラグの文字だけが使われます.
  • フラグが引数を取らないブーリアンである場合には修飾子を付けません.
  • フラグが引数を要求し,指定された最後の値のみを保存する場合は修飾子=を付けます.
  • フラグが省略可能な引数を取り,指定された最後の値のみを保存する場合は修飾子=?を付けます.
  • フラグが引数を要求し,指定されたすべての値を保存する場合は修飾子=+を付けます. !に続けて値の検査をするためのfishスクリプトを続けることができます.ほとんどの場合,このfishスクリプトは関数呼び出しです.終了ステータスがゼロである場合,そのフラグの値は有効です.終了ステータスが非ゼロの場合は値が無効です.エラーメッセージは(stderrにではなく)stdoutに書き出してください.詳細はフラグの値検査を参照してください.

オプション使用を生成するための,より親切だが冗長な方法に関してはfish_optコマンドを参照してください.

以下の例において,引数解析時にフラグが見つからなかった場合,対応する_flag_X変数は定義されません.

フラグの値検査

ある基準を満たすために,オプションとして与えられた値の検査をしたくなるのはよくあることです. ユーザはargparseが値を返した後にそれを行うことができますが,argparseが任意のfishスクリプトを実行して検査を行うようリクエストすることができます. そうするには単に!(エクスクラメーションマーク)を書き,実効すべきfishスクリプトを続けて書きます. そのコードが実行されるとき,以下の3つの変数が定義されます.

  • _argparse_cmdにはargparse --nameの値がセットされます.
  • _flag_nameには処理中のショートフラグあるいはロングフラグがセットされます.
  • _flag_valueには処理中のフラグに関連付けられた値がセットされます.

もし関数を使うのなら,関数は--no-scope-shadowingフラグ付きで定義されるべきです.さもなければ,その関数はこれらの変数にアクセスできません.

スクリプトはエラーメッセージをstderrにではなくstdoutに書き出すべきです. フラグの値が有効ならステータスとしてゼロを返し,そうでなければ,フラグが無効であることを示す非ゼロのステータスを返すべきです.

fishは--minフラグと--maxフラグを受け付ける_validate_int関数を提供します. ユーザのコマンドが-mあるいは--maxフラグを受け付け,許される最小値がゼロで最大値が5であるとします. ユーザはオプションを次のように定義できます.m/max=!_validate_int --min 0 --max 5 ユーザが_validate_intをフラグ無しで呼び出した場合のデフォルトでは,最小値および最大値の制限なしに単に値が整数であるかどうかをチェックします.

オプション指定の例

いくつかのオプション指定の例:

  • h/help-h--helpの両方が有効であることを意味します.このフラグはブーリアンで複数回使用可能です.いずれかのフラグが使用されたなら,_flag_h_flag_helpにはいずれかのフラグが何回使用されたかがセットされます.
  • h-help--helpのみが有効であることを意味します.このフラグはブーリアンで複数回使用可能です.ロングフラグが使用されたなら,_flag_h_flag_helpにはいずれかのフラグが何回使用されたかがセットされます.
  • n/name=-n--nameの両方が有効であることを意味します.これは値を要求し,最大で一度だけ使用できます.このフラグが使用されたなら,_flag_n_flag_nameにそのフラグに関連付けられた必須の値がセットされます.
  • n/name=?-n--nameの両方が有効であることを意味します.これは値を受け取ることができ,最大で一度だけ使用できます.このフラグが使用されたなら,_flag_n_flag_nameにそのフラグに関連付けられた値が,それが与えられた場合にはセットされ,そうでなければ空の値がセットされます.
  • n/name=+-n--nameの両方が有効であることを意味します.これは値を受け取ることができ,複数回使用できます.このフラグが使用されたなら,フラグが使用された回数分,_flag_n_flag_nameにフラグに関連付けられた値がセットされます.
  • x-xだけが有効であることを意味します.このフラグはブーリアンで複数回使用可能です.このフラグが使用されたなら,_flag_xにフラグが何回使用されたかがセットされます.
  • x=, x=?, x=+は上に示したn/nameの例と似ていますが,ショートフラグ-xの代用となるロングフラグが存在しません.
  • x-はロングフラグ名がないため無効であり,ショートフラグ-xを使うべきです.これはオプション指定に:, ::, +が含まれているかどうかによらず常に真です.(訳注: :::, +はGitHubでargparseコマンドが提案された際の古い記法です.現在では=, =?, =+が使われています)
  • #-maxは正規表現’ˆ--?\d+$’にマッチするフラグが有効であることを意味します.これらのフラグが使用されたなら,変数_flag_maxへと割り当てられます.この方法はひとつの'-'を前置することにより正値あるいは負値の整数を指定することを可能にします.多くのコマンドがこのイディオムをサポートしています.たとえばhead -3 /a/fileは/a/fileの最初の3行のみを表示します. n::maxは正規表現’ˆ--?\d+$’にマッチするフラグが有効であることを意味します.これらのフラグが使用されたなら,変数_flag_n_flag_maxへと割り当てられます.この方法はひとつの'-'を前置することにより正値あるいは負値の整数を指定することを可能にします.多くのコマンドがこのイディオムをサポートしています.たとえばhead -3 /a/fileは/a/fileの最初の3行のみを表示します.ユーザはフラグによって値を指定することもできます.この例では-n NNNあるいは--max NNNです.(訳注: n::maxという記法は使用できません.代わりにn#maxを使ってください)

引数の解析後,ローカルスコープのargv変数にはフラグ処理の間に消費されなかったすべての値がセットされています.もしフラグに結び付けられていない値がなければ,変数はセットされますがcount $argvはゼロになります.

もし引数解析の間にエラーが生じたなら,非ゼロのステータスで終了し適切なエラーメッセージがstderrに出力されます.

覚え書き

リリース2.7.0でこのビルトインコマンドが追加される以前には,スクリプトや関数に渡される値を解析する二つの主要な方法がありました. 一つの方法はOSが提供するgetoptコマンドを使うことです. この方法の問題点はGNU実装とBSD実装に互換性がないことです. このことは、単純な状況以外では、この外部コマンドの使用を困難にします. もう一つの方法は,引数をどう扱うか判断するために$argvを走査してfishのswitch文を使うことです. しかしこの方法は大量のボイラープレート・コードを含むことになります. また、組み込みコマンドと同じ動作を実装することも不可能です.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment