次の方法で共有


構文の概要: コマンド、オプション、および引数

重要

System.CommandLine は現在プレビュー段階であり、このドキュメントはバージョン 2.0 ベータ 5 用です。 一部の情報は、リリース前に大幅に変更される可能性があるプレリリース製品に関連しています。 Microsoft は、ここで提供される情報に関して明示的または黙示的な保証を行いません。

この記事では、 System.CommandLine 認識されるコマンド ライン構文について説明します。 この情報は、 .NET CLI を含む .NET コマンド ライン アプリのユーザーと開発者の両方に役立ちます。

トークン

System.CommandLine は、コマンド ライン入力 をトークンに解析します。トークンは、スペースで区切られた文字列です。 たとえば、次のコマンド ラインを考えてみます。

dotnet tool install dotnet-suggest --global --verbosity quiet

この入力は、 dotnet アプリケーションによってトークン toolinstalldotnet-suggest--global--verbosity、および quietに解析されます。

トークンは、コマンド、オプション、または引数として解釈されます。 呼び出されるコマンド ライン アプリによって、最初のトークンの後のトークンの解釈方法が決まります。 次の表は、 System.CommandLine 前の例を解釈する方法を示しています。

トークン 解析結果
tool サブコマンド
install サブコマンド
dotnet-suggest install コマンドの引数
--global インストール コマンドのオプション
--verbosity インストール コマンドのオプション
quiet --verbosity オプションの引数

トークンは、引用符 (") で囲まれている場合にスペースを含めることができます。 次に例を示します。

dotnet tool search "ef migrations add"

コマンド

コマンド ライン入力の コマンド は、アクションを指定するか、関連するアクションのグループを定義するトークンです。 例えば次が挙げられます。

  • dotnet runでは、runはアクションを指定するコマンドです。
  • dotnet tool installでは、installはアクションを指定するコマンドであり、toolは関連するコマンドのグループを指定するコマンドです。 tool uninstalltool listtool updateなど、ツール関連のコマンドは他にもあります。

Root コマンド

ルート コマンドは、アプリの実行可能ファイルの名前を指定するものです。 たとえば、 dotnet コマンドは 、dotnet.exe 実行可能ファイルを指定します。

System.CommandLine.Command は任意のコマンドまたはサブコマンドの汎用クラスですが、 System.CommandLine.RootCommand はアプリケーションのルート エントリ ポイントを対象とした特殊なバージョンであり、 System.CommandLine.Command のすべての機能を継承しますが、 ヘルプ オプションバージョン オプションSuggest ディレクティブなどのルート固有の動作と既定値を追加します。

サブコマンド

ほとんどのコマンド ライン アプリでは、 動詞とも呼ばれるサブコマンド がサポートされています。 たとえば、dotnet コマンドには、runを入力して呼び出すdotnet runサブコマンドがあります。

サブコマンドは、独自のサブコマンドを持つことができます。 dotnet tool installでは、installtoolのサブコマンドです。

サブコマンドは、次の例に示すように追加できます。

RootCommand rootCommand = new();

Command sub1Command = new("sub1", "First-level subcommand");
rootCommand.Subcommands.Add(sub1Command);

Command sub1aCommand = new("sub1a", "Second level subcommand");
sub1Command.Subcommands.Add(sub1aCommand);

この例の最も内側のサブコマンドは、次のように呼び出すことができます。

myapp sub1 sub1a

オプション

オプションは、コマンドに渡すことができる名前付きパラメーターです。 POSIX CLI は通常、オプション名の前に 2 つのハイフン (--) を付けます。 次の例は、2 つのオプションを示しています。

dotnet tool update dotnet-suggest --verbosity quiet --global
                                  ^---------^       ^------^

この例が示すように、オプションの値は明示的 (quietの場合は--verbosity) または暗黙的 (--globalに続くものはありません) にすることができます。 値が指定されていないオプションは、通常、コマンド ラインでオプションが指定されている場合に既定で true されるブール型パラメーターです。

一部の Windows コマンド ライン アプリでは、オプション名の先頭にスラッシュ (/) を使用してオプションを識別します。 例えば次が挙げられます。

msbuild /version
        ^------^

System.CommandLine では、POSIX と Windows の両方のプレフィックス規則がサポートされています。

オプションを構成するときは、プレフィックスを含むオプション名を指定します。

Option<int> delayOption = new("--delay", "-d")
{
    Description = "An option whose argument is parsed as an int.",
    DefaultValueFactory = parseResult => 42,
};
Option<string> messageOption = new("--message", "-m")
{
    Description = "An option whose argument is parsed as a string."
};

RootCommand rootCommand = new();
rootCommand.Options.Add(delayOption);
rootCommand.Options.Add(messageOption);

オプションをコマンドに追加し、そのすべてのサブコマンドに再帰的に追加するには、 System.CommandLine.Symbol.Recursive プロパティを使用します。

必須オプション

一部のオプションには必須の引数があります。 たとえば、.NET CLI では、 --output にはフォルダー名の引数が必要です。 引数が指定されていない場合、コマンドは失敗します。 オプションを必須にするには、次の例に示すように、 System.CommandLine.Symbol.Required プロパティを true に設定します。

Option<FileInfo> fileOption = new("--output")
{
    Required = true
};

必要なオプションに既定値 ( DefaultValueFactory プロパティを使用して指定) がある場合、コマンド ラインでオプションを指定する必要はありません。 その場合、既定値は必要なオプション値を提供します。

議論

引数は、コマンドに渡すことができる名前のないパラメーターです。 次の例は、 build コマンドの引数を示しています。

dotnet build myapp.csproj
             ^----------^

引数を構成するときは、引数名を指定し (解析には使用されませんが、名前で解析された値を取得したり、ヘルプを表示したりするために使用できます)、次のように入力します。

Argument<int> delayArgument = new("delay")
{
    Description = "An argument that is parsed as an int.",
    DefaultValueFactory = parseResult => 42
};
Argument<string> messageArgument = new("message")
{
    Description = "An argument that is parsed as a string."
};

RootCommand rootCommand = new();
rootCommand.Arguments.Add(delayArgument);
rootCommand.Arguments.Add(messageArgument);

既定値

引数とオプションの両方に、引数が明示的に指定されていない場合に適用される既定値を指定できます。 たとえば、オプション名がコマンド ラインにある場合、多くのオプションは暗黙的にブール型パラメーターであり、既定値は true です。 次のコマンド ラインの例は同等です。

dotnet tool update dotnet-suggest --global
                                  ^------^

dotnet tool update dotnet-suggest --global true
                                  ^-----------^

既定値なしで定義されている引数は、必須の引数として扱われます。

解析エラー

オプションと引数には予期される型があり、値を解析できない場合にエラーが生成されます。 たとえば、"silent" は --verbosityの有効な値の 1 つではないので、次のコマンド エラーが発生します。

dotnet build --verbosity silent
Option<string> verbosityOption = new("--verbosity", "-v")
{
    Description = "Set the verbosity level.",
};
verbosityOption.AcceptOnlyFromAmong("quiet", "minimal", "normal", "detailed", "diagnostic");
RootCommand rootCommand = new() { verbosityOption };

ParseResult parseResult = rootCommand.Parse(args);
foreach (ParseError parseError in parseResult.Errors)
{
    Console.WriteLine(parseError.Message);
}
Argument 'silent' not recognized. Must be one of:
        'quiet'
        'minimal'
        'normal'
        'detailed'
        'diagnostic'

引数には、指定できる値の数に関する期待値もあります。 引数の アリティに関するセクションでは、例を示します。

オプションと引数の順序

コマンドラインでオプションの前に引数を、または引数の前にオプションを指定することができます。 次のコマンドは同等です。

dotnet add package System.CommandLine --prerelease
dotnet add package --prerelease System.CommandLine

オプションは任意の順序で指定できます。 次のコマンドは同等です。

dotnet add package System.CommandLine --prerelease --no-restore --source https://api.nuget.org/v3/index.json
dotnet add package System.CommandLine --source https://api.nuget.org/v3/index.json --no-restore --prerelease

複数の引数がある場合、順序は重要です。 次のコマンドは同等ではありません。値の順序が異なるため、結果が異なる可能性があります。

myapp argument1 argument2
myapp argument2 argument1

エイリアス

POSIX と Windows の両方で、一部のコマンドとオプションにエイリアスが含まれるのが一般的です。 これらは通常、簡単に入力できる短いフォームです。 エイリアスは、 大文字と小文字 の区別をシミュレートしたり、単語の代替スペルをサポートしたりするために、他の目的にも使用できます。

POSIX の短い形式では、通常、先頭にハイフンが 1 つ続き、1 文字が続きます。 次のコマンドは同等です。

dotnet build --verbosity quiet
dotnet build -v quiet

GNU 標準では、自動エイリアスが推奨されています。 つまり、長い形式のコマンドまたはオプション名の任意の部分を入力できます。これは受け入れられます。 この動作により、次のコマンド ラインが同等になります。

dotnet publish --output ./publish
dotnet publish --outpu ./publish
dotnet publish --outp ./publish
dotnet publish --out ./publish
dotnet publish --ou ./publish
dotnet publish --o ./publish

System.CommandLine では、自動エイリアスはサポートされていません。 各エイリアスは明示的に指定する必要があります。 コマンドとオプションの両方で、 Aliases プロパティが公開されます。 Option には、パラメーターとしてエイリアスを受け入れるコンストラクターがあるため、1 行に複数のエイリアスを含むオプションを定義できます。

Option<bool> helpOption = new("--help", ["-h", "/h", "-?", "/?"]);
Command command = new("serialize") { helpOption };
command.Aliases.Add("serialise");

定義するオプション エイリアスの数を最小限に抑え、特定のエイリアスを特に定義しないようにすることをお勧めします。 詳細については、「 短い形式のエイリアス」を参照してください。

大文字小文字の区別

コマンド名とオプション名とエイリアスは、POSIX 規則に従って既定で大文字と小文字が区別され、 System.CommandLine はこの規則に従います。 CLI で大文字と小文字を区別しないようにするには、さまざまな大文字と小文字を使用した代替のエイリアスを定義します。 たとえば、--additional-probing-path--Additional-Probing-Path--ADDITIONAL-PROBING-PATH というエイリアスを持つことができます。

一部のコマンド ライン ツールでは、大文字と小文字の違いによって機能の違いが指定されます。 たとえば、 git clean -X の動作は git clean -xとは異なります。 .NET CLI はすべて小文字です。

列挙型に基づくオプションの引数値には、大文字と小文字の区別は適用されません。 列挙型名は、大文字と小文字に関係なく照合されます。

-- トークン

POSIX 規則は、二重ダッシュ (--) トークンをエスケープ メカニズムとして解釈します。 二重ダッシュ トークンに続くすべてのものは、コマンドの引数として解釈されます。 この機能を使用すると、オプションとして解釈できなくなるため、オプションのような引数を送信できます。

myappmessage引数を受け取り、messageの値を--interactiveしたいとします。 次のコマンド ラインでは、予期しない結果が得られます。

myapp --interactive

myapp--interactiveオプションがない場合、--interactive トークンは引数として解釈されます。 ただし、アプリに --interactive オプションがある場合、この入力はそのオプションを参照していると解釈されます。

次のコマンド ラインでは、二重ダッシュ トークンを使用して、 message 引数の値を "--interactive" に設定します。

myapp -- --interactive
      ^^

System.CommandLine では、この二重ダッシュ機能がサポートされています。

オプション引数の区切り記号

System.CommandLine では、オプション名とその引数の間の区切り記号として、スペース '=' または ':' を使用できます。 たとえば、次のコマンドは同等です。

dotnet build -v quiet
dotnet build -v=quiet
dotnet build -v:quiet

POSIX 規則を使用すると、1 文字のオプション エイリアスを指定するときに区切り記号を省略できます。 たとえば、次のコマンドは同等です。

myapp -vquiet
myapp -v quiet

System.CommandLine では、この構文が既定でサポートされています。

引数のアリティ

オプションまたはコマンドの引数の アリティ は、そのオプションまたはコマンドが指定されている場合に渡すことができる値の数です。

Arity は、次の表に示すように、最小値と最大値で表されます。

マックス 有効性の例
0 0 有効: --ファイル
無効です: --file a.json
無効です: --file a.json --file b.json
0 1 有効: --旗
有効: --flag true
有効: --flag false
無効です: --flag false --flag false
1 1 有効: --file a.json
無効です: --ファイル
無効です: --file a.json --file b.json
0 n 有効: --ファイル
有効: --file a.json
有効: --file a.json --file b.json
1 n 有効: --file a.json
有効: --file a.json b.json
無効です: --ファイル

System.CommandLine には、アリティを定義するための System.CommandLine.ArgumentArity 構造体があり、次の値があります。

  • System.CommandLine.ArgumentArity.Zero - 値は許可されません。
  • System.CommandLine.ArgumentArity.ZeroOrOne - 1 つの値を持つ場合があり、値がない場合があります。
  • System.CommandLine.ArgumentArity.ExactlyOne - 1 つの値が必要です。
  • System.CommandLine.ArgumentArity.ZeroOrMore - 1 つの値、複数の値、または値がない場合があります。
  • System.CommandLine.ArgumentArity.OneOrMore - 複数の値を持つ場合があり、少なくとも 1 つの値が必要です。

Arity プロパティを使用してアリティを明示的に設定できますが、ほとんどの場合は不要です。 System.CommandLine は、引数の型に基づいて引数のアリティを自動的に決定します。

引数タイプ 既定のアリティ
Boolean ArgumentArity.ZeroOrOne
コレクション型 ArgumentArity.ZeroOrMore
その他すべて ArgumentArity.ExactlyOne

オプションのオーバーライド

アリティの最大値が 1 の場合でも、 System.CommandLine はオプションの複数のインスタンスを受け入れるように構成できます。 その場合、繰り返しオプションの最後のインスタンスは、以前のインスタンスを上書きします。 次の例では、値 2 が myapp コマンドに渡されます。

myapp --delay 3 --message example --delay 2

複数の引数

既定では、コマンドを呼び出すときに、オプション名を繰り返して、最大 アリティ が 1 より大きいオプションに対して複数の引数を指定できます。

myapp --items one --items two --items three

オプション名を繰り返さずに複数の引数を許可するには、 System.CommandLine.Option.AllowMultipleArgumentsPerTokentrue に設定します。 この設定では、次のコマンド ラインを入力できます。

myapp --items one two three

引数の最大アリティが 1 の場合、同じ設定の効果が異なります。 オプションを繰り返すことができますが、行の最後の値のみを受け取ります。 次の例では、 three 値がアプリに渡されます。

myapp --item one --item two --item three

オプションバンドル

POSIX では、スタックとも呼ばれる 1 文字のオプションのバンドルをサポートすることをお勧めします。 バンドルされたオプションは、1 つのハイフンプレフィックスの後に一緒に指定される 1 文字のオプションエイリアスです。 引数を指定できるのは最後のオプションだけです。 たとえば、次のコマンド ラインは同等です。

git clean -f -d -x
git clean -fdx

オプション バンドルの後に引数を指定すると、バンドル内の最後のオプションに適用されます。 次のコマンド ラインは同等です。

myapp -a -b -c arg
myapp -abc arg

この例のどちらのバリアントでも、引数 arg はオプション -cにのみ適用されます。

ブール型のオプション (フラグ)

true引数を持つオプションに対してfalseまたはboolが渡された場合は、想定どおりに解析されます。 ただし、引数の型が bool オプションでは、通常、引数を指定する必要はありません。 ブール型のオプション ("flags" とも呼ばれます) には、通常、System.CommandLine.ArgumentArity.ZeroOrOneがあります。 コマンド ラインにオプション名が存在し、その後に引数が指定されていない場合、既定値は true になります。 コマンド ライン入力にオプション名が指定されていないと、 falseの値になります。 myapp コマンドで --interactive という名前のブール値オプションの値が出力される場合、次の入力によって次の出力が作成されます。

myapp
myapp --interactive
myapp --interactive false
myapp --interactive true
False
True
False
True

バージョン オプション

System.CommandLine上に構築されたアプリは、root コマンドで使用される --version オプションに応じて、バージョン番号を自動的に提供します。 例えば次が挙げられます。

dotnet --version
6.0.100

応答ファイル

応答ファイルは、コマンド ライン アプリの一連のトークンを含むファイルです。 応答ファイルは、次の 2 つのシナリオで役立つ System.CommandLine の機能です。

  • ターミナルの文字制限より長い入力を指定してコマンド ライン アプリを呼び出す。
  • 行全体を再入力せずに同じコマンドを繰り返し呼び出す。

応答ファイルを使用するには、コマンド、オプション、および引数を挿入する行の任意の場所に、 @ 記号が付いたファイル名を入力します。 rsp ファイル拡張子は一般的な規則ですが、任意のファイル拡張子を使用できます。

次の行は同等です。

dotnet build --no-restore --output ./build-output/
dotnet @sample1.rsp
dotnet build @sample2.rsp --output ./build-output/

sample1.rsp の内容:

build
--no-restore
--output
./build-output/

sample2.rsp の内容:

--no-restore

応答ファイル内のテキストの解釈方法を決定する構文規則を次に示します。

  • トークンはスペースで区切られます。 おはよう! を含む行は、Good and morning! という 2 つのトークンとして扱われます。
  • 引用符で囲まれた複数のトークンは、1 つのトークンとして解釈されます。 "おはよう!" を含む行は、1 つのトークンとして扱われます。おはようございます!
  • #記号と行末の間のテキストはコメントとして扱われ、無視されます。
  • @プレフィックスが付いたトークンは、追加の応答ファイルを参照できます。
  • 応答ファイルには複数行のテキストを含めることができます。 行は連結され、トークンのシーケンスとして解釈されます。

指示事項

System.CommandLineでは、System.CommandLine.Directive型で表されるディレクティブと呼ばれる構文要素が導入されています。 [diagram] ディレクティブは一例です。 アプリの名前の後に [diagram] を含めると、 System.CommandLine コマンド ライン アプリを呼び出す代わりに解析結果の図が表示されます。

dotnet [diagram] build --no-restore --output ./build-output/
       ^-----^
[ dotnet [ build [ --no-restore <True> ] [ --output <./build-output/> ] ] ]

ディレクティブの目的は、コマンドライン アプリ間で適用できるクロスカット機能を提供することです。 ディレクティブは構文的にアプリ独自の構文とは異なるため、アプリ間で適用される機能を提供できます。

ディレクティブは、次の構文規則に準拠している必要があります。

  • これは、コマンド ライン上のトークンであり、アプリの名前の後に、サブコマンドまたはオプションの前に置かれます。
  • 角かっこで囲む。
  • スペースを含まない。

認識できないディレクティブは、解析エラーを引き起こさずに無視されます。

ディレクティブには、ディレクティブ名からコロンで区切られた引数を含めることができます。

次のディレクティブが組み込まれています。

[diagram] ディレクティブ

ユーザーと開発者の両方が、アプリが特定の入力をどのように解釈するかを確認すると便利な場合があります。 System.CommandLine アプリの既定の機能の 1 つは、コマンド入力の解析結果をプレビューできる[diagram] ディレクティブです。 例えば次が挙げられます。

myapp [diagram] --delay not-an-int --interactive --file filename.txt extra
![ myapp [ --delay !<not-an-int> ] [ --interactive <True> ] [ --file <filename.txt> ] *[ --fgcolor <White> ] ]   ???--> extra

前の例では、次のようになります。

  • コマンド (myapp)、その子オプション、およびそれらのオプションの引数は、角かっこを使用してグループ化されます。
  • オプションの結果 [ --delay !<not-an-int> ]の場合、 ! は解析エラーを示します。 not-an-int オプションに対する値 int は、想定された型に解析できません。 エラーは、エラーが発生したオプションを含むコマンドの前に ! によってもフラグが設定されます: ![ myapp...
  • オプションの結果 *[ --fgcolor <White> ]では、コマンド ラインでオプションが指定されていないため、構成済みの既定値が使用されました。 White は、このオプションの有効な値です。 アスタリスクは、値が既定値であることを示します。
  • ???--> は、アプリのコマンドまたはオプションのいずれにも一致しなかった入力を指します。

Suggest ディレクティブ

[suggest] ディレクティブを使用すると、正確なコマンドがわからない場合にコマンドを検索できます。

dotnet [suggest] buil
build
build-server
msbuild

こちらもご覧ください