共用方式為


語法概觀:命令、選項和自變數

本文說明可辨識的命令行語法 System.CommandLine 。 此資訊對 .NET 命令行應用程式的用戶和開發人員都很有用,包括 .NET CLI

代幣

System.CommandLine 將命令列輸入剖析為 標記,這是以空格分隔的字串。 例如,請考慮下列命令列:

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

這個輸入會由dotnet應用程式剖析成令牌tool、、installdotnet-suggest--global--verbosityquiet

令牌會解譯為命令、選項或自變數。 被調用的命令行應用程式會決定第一個令牌及後續令牌的解釋方式。 下表顯示如何 System.CommandLine 解譯上述範例:

代幣 解析為
tool 子命令
install 子命令
dotnet-suggest 安裝命令的參數
--global 安裝命令的選項
--verbosity 安裝命令的選項
quiet 選項的自變數--verbosity

若令牌以引號(")括住,則可包含空格。 以下為範例:

dotnet tool search "ef migrations add"

符號階層(命令、選項、引數)會被視為受信任的輸入;令牌值不是。

指令

命令行輸入中的 命令 是指定動作或定義相關動作群組的令牌。 例如:

  • 在 中 dotnet runrun 是指定動作的命令。
  • 在 中 dotnet tool installinstall 是指定動作的命令,而 tool 是指定相關命令群組的命令。 還有其他工具相關命令,例如 tool uninstalltool listtool update

根命令

根命令是指定應用程式可執行檔名稱的命令。 例如, dotnet 命令會指定 dotnet.exe 可執行檔。

Command 是任何命令或子命令的一般用途類別,而 RootCommand 是專用於應用程式根進入點的特製化版本。 RootCommand 繼承了 Command 的所有功能,但會新增根特定行為和預設值,例如 [說明] 選項[版本] 選項[建議] 指示詞

子命令

大部分的命令行應用程式都支援 子命令,也稱為 動詞命令。 例如, 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 CLIS 通常會在選項名稱前面加上兩個連字元 (--)。 下列範例顯示兩個選項:

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 需要資料夾名稱自變數。 如果未提供 自變數,命令會失敗。 若要讓選項成為必要選項,請將其 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」不是其中一個有效值:

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 簡短形式通常具有單一前置連字號,後面接著單一字元。 下列命令是相等的:

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 具有接受別名做為參數的建構函式,因此您可以在單行中定義具有多個別名的選項:

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 慣例會將雙連字元(--)標記解釋為逸出機制。 在雙破折號標記之後的所有內容將被解釋為命令的參數。 這項功能可以用來提交看起來像選項的自變數,因為它可防止它們解譯為選項。

假設 myapp 接受一個 message 參數,而您想要 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 慣例可讓您在指定單一字元選項別名時省略分隔符。 例如,下列命令相等:

myapp -vquiet
myapp -v quiet

System.CommandLine 默認支援此語法。

引數元數

選項或命令自變數的 arity 是指定該選項或命令時可以傳遞的值數目。

Arity 會以最小值和最大值來表示,如下表所示:

最小值 麥克斯 範例有效性 範例
0 0 有效: --檔
不合法: --檔案 a.json
不合法: --檔案 a.json --檔案 b.json
0 1 有效: --旗標
有效: --旗標為真
有效: --旗標 false
不合法: --旗幟 false --旗幟 false
1 1 有效: --檔案 a.json
不合法: --檔
不合法: --檔案 a.json --檔案 b.json
0 n 有效: --檔
有效: --檔案 a.json
有效: --檔案 a.json --檔案 b.json
1 n 有效: --檔案 a.json
有效: --檔案 a.json b.json
不合法: --檔

System.CommandLine ArgumentArity具有定義arity的結構,其值為下列值:

  • Zero - 不允許有任何數值。
  • ZeroOrOne - 可以有一個值或沒有值。
  • ExactlyOne - 必須有一個值。
  • ZeroOrMore - 可以有一個值、多個值或沒有值。
  • OneOrMore - 可以有多個值;必須至少有一個值。

您可以使用 Arity 屬性明確設定 arity,但在大多數情況下不需要。 System.CommandLine 會根據參數類型自動判斷參數的參數數量:

引數類型 默認arity
Boolean ArgumentArity.ZeroOrOne
集合類型 ArgumentArity.ZeroOrMore
其他所有項目 ArgumentArity.ExactlyOne

選項設定覆寫

如果 arity 最大值為 1, System.CommandLine 仍可設定為接受選項的多個實例。 在此情況下,重複選項的最後一個實例會覆寫任何先前的實例。 在下列範例中,值 2 會傳遞至 myapp 命令。

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

多個參數

根據預設,當您呼叫命令時,您可以重複選項名稱,為具有最大 arity 大於一的選項指定多個自變數。

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

若要允許多個自變數而不重複選項名稱,請將 設定 AllowMultipleArgumentsPerTokentrue。 這個設定可讓您輸入下列命令列。

myapp --items one two three

如果最大自變數 arity 為 1,則相同的設定會有不同的效果。 它可讓您重複選項,但只會接受該行的最後一個值。 在下列範例中,值 three 會傳遞至應用程式。

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

選項組合

POSIX 建議您支援連結單一字元選項,也稱為堆疊。 選項組合是指在單一連字元(-)後面一起指定的多個單一字元選項別名。 只有最後一個選項可以指定自變數。 例如,下列命令列是相等的:

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

如果在選項組合之後提供自變數,它會套用至套件組合中的最後一個選項。 下列命令列是相等的:

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

在這裡範例中的這兩個變體中,自變數 arg 只會套用至 選項 -c

布林選項 (旗標)

如果將 truefalse 傳遞至需要 bool 參數的選項,則會如預期般進行剖析。 但參數類型為 bool 的選項通常不需要指定參數。 布爾值選項,有時稱為「旗標」,通常具有元數ZeroOrOne。 命令列上選項名稱的存在,且其後沒有自變數,會導致預設值 true為 。 選項名稱若未在命令列輸入中出現,其值為falsemyapp如果命令列印出名為 --interactive的布林選項值,下列輸入會建立下列輸出:

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

版本選項

建置於 System.CommandLine 上的應用程式會自動提供版本號碼,以回應與根命令搭配使用的 --version 選項。 例如:

dotnet --version
6.0.100

回應檔

回應檔是一個檔案,其中包含命令行應用程式的一組令牌。 回應檔是 的一項功能 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

以下是決定回應檔中文字解譯方式的語法規則:

  • 令牌會以空格分隔。 包含早安! 的一行會被視為兩個標記:好早!
  • 以引號括住的多個令牌會解譯為單一令牌。 包含 「早安!」 的一行會被視為一個標記 「早安!」。
  • 符號與行尾之間的 # 任何文字都會被視為批注並忽略。
  • @ 作為字首的令牌可以參考其他響應檔案。
  • 回應檔可以有多個文字行。 這些行會串連並解譯為一連串的符號。

指令

System.CommandLine引進名為指示詞的語法元素,由Directive類型表示。 例如,指令是內建指令。 當您在應用程式名稱之後包含 [diagram] 時, System.CommandLine 會顯示剖析結果的圖表,而不是叫用命令行應用程式:

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

指令的目的是提供可在命令行應用程式中運用的跨領域功能。 由於指示詞在語法上與應用程式本身的語法不同,因此它們可以提供跨應用程式套用的功能。

指示詞必須符合下列語法規則:

  • 這是命令行上的令牌,位於應用程式名稱之後,但在任何子命令或選項之前。
  • 它以方括弧括起來。
  • 它不包含空格。

將忽略無法辨識的指令,而不會造成剖析錯誤。

指示詞可以包含自變數,並以冒號分隔指示詞名稱。

下列指令是內建的:

[diagram] 指令

用戶和開發人員都可能會發現應用程式如何解譯指定的輸入會很有用。 應用程式的其中一個 System.CommandLine 預設特徵是 [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-intint選項值無法解析成預期的類型。 錯誤也會在 ! 包含錯誤選項的命令前面加上標記:![ myapp...
  • 針對選項結果 *[ --fgcolor <White> ],未在命令行上指定選項,因此會使用已設定的預設值。 White 是這個選項的有效值。 星號表示值為預設值。
  • ???--> 指向與任何應用程式命令或選項不相符的輸入。

建議指令

[suggest] 指令可讓您在不知道確切命令時搜尋命令。

dotnet [suggest] buil
build
build-server
msbuild

另請參閱