System.CommandLine 的命令列語法概觀
重要
System.CommandLine
目前為預覽版,而此文件適用於版本 2.0 搶鮮版 (Beta) 4。
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
本文說明 System.CommandLine
可辨識的命令列語法。 此資訊對包括 .NET CLI 在內之 .NET 命令列應用程式的使用者和開發人員都很有幫助。
語彙基元
System.CommandLine
會將命令列輸入剖析為權杖,它們是以空格分隔的字串。 例如,請考慮以下命令列:
dotnet tool install dotnet-suggest --global --verbosity quiet
dotnet
應用程式會將此輸入剖析為權杖 tool
、install
、dotnet-suggest
、--global
、--verbosity
和 quiet
。
權杖會解譯為命令、選項或引數。 正被叫用的命令列應用程式會決定如何解譯第一個權杖之後的其他權杖。 下表顯示 System.CommandLine
如何解譯上述範例:
Token | 剖析為 |
---|---|
tool |
子命令 |
install |
子命令 |
dotnet-suggest |
安裝命令的引數 |
--global |
安裝命令的選項 |
--verbosity |
安裝命令的選項 |
quiet |
--verbosity 選項的引數 |
如果將權杖以引號括住,就可以包含空格 ("
)。 以下是範例:
dotnet tool search "ef migrations add"
命令
輸入命令列的命令是指定動作或定義相關動作群組的權杖。 例如:
- 在
dotnet run
中,run
是指定動作的命令。 - 在
dotnet tool install
中,install
是指定動作的命令,而tool
是指定相關命令群組的命令。 還有其他工具相關命令,例如tool uninstall
、tool list
和tool update
。
根命令
根命令是指定應用程式可執行檔名稱的命令。 例如,dotnet
命令會指定 dotnet.exe 可執行檔。
子命令
大部分命令列應用程式都支援子命令,也稱為 動詞命令。 例如,輸入 dotnet run
即可叫用 dotnet
命令中的 run
子命令。
子命令可以有自己的子命令。 在 dotnet tool install
中,install
是 tool
的子命令。
選項。
選項是可傳遞至命令的具名參數。 POSIX CLIS 通常會在選項名稱前面加上兩個連字元(--
)。 以下範例示範兩個選項:
dotnet tool update dotnet-suggest --verbosity quiet --global
^---------^ ^------^
如本範例所示,選項的值可為明確 (quiet
之於 --verbosity
) 或隱含 (--global
後無任何值)。 如果在命令列上指定選項,則不指定任何值的選項通常是 true
預設的布林參數。
有些 Windows 命令列應用程式使用前置斜線 (/
) 加選項名稱來識別選項。 例如:
msbuild /version
^------^
System.CommandLine
同時支援 POSIX 和 Windows 前置詞慣例。 設定選項時,您可以指定包含前置詞的選項名稱。
引數
引數是傳遞至選項或命令的值。 下列範例顯示 verbosity
選項的引數和 build
命令的引數。
dotnet tool update dotnet-suggest --verbosity quiet --global
^---^
dotnet build myapp.csproj
^----------^
如未明確提供引數,可以適合的預設值代替引數。 例如,當選項名稱位於命令列時,許多選項都隱含布林參數,預設值為 true
。 下列命令列範例有相同的效果:
dotnet tool update dotnet-suggest --global
^------^
dotnet tool update dotnet-suggest --global true
^-----------^
有些選項具有必要的引數。 例如,在 .NET CLI 中,--output
需要有資料夾名稱引數。 如未提供該引數,則命令會失敗。
引數可以有預期的類型,如果引數無法剖析為預期的類型,System.CommandLine
即會顯示錯誤訊息。 例如,下列命令錯誤的成因乃 "silent" 不是有效的 --verbosity
值之一:
dotnet build --verbosity silent
Cannot parse argument 'silent' for option '-v' as expected type 'Microsoft.DotNet.Cli.VerbosityOptions'. Did you mean one of the following?
Detailed
Diagnostic
Minimal
Normal
Quiet
引數也有預期的值可提供個數。 請參閱引數的參數個數一節提供的範例。
選項和引數的順序
您可以在命令列中先提供選項再提供引數,或先提供引數再提供選項。 下列命令有相同的效果:
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
不支援自動別名。
區分大小寫
根據 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 預設支援此語法。
引數的參數個數
選項或命令引數的參數個數,是指定選項或命令時可傳遞的值的個數。
參數個數會以最小值和最大值表示,如下表所示:
Min | Max | 範例有效性 | 範例 |
---|---|---|---|
0 | 0 | 有效: | --file |
無效: | --file a.json | ||
無效: | --file a.json --file b.json | ||
0 | 1 | 有效: | --flag |
有效: | --flag true | ||
有效: | --flag false | ||
無效: | --flag false --flag false | ||
1 | 1 | 有效: | --file a.json |
無效: | --file | ||
無效: | --file a.json --file b.json | ||
0 | n | 有效: | --file |
有效: | --file a.json | ||
有效: | --file a.json --file b.json | ||
1 | n | 有效: | --file a.json |
有效: | --file a.json b.json | ||
無效: | --file |
System.CommandLine
的 ArgumentArity 結構用於定義參數個數,包含下列值:
- Zero - 不允許任何值。
- ZeroOrOne - 可有一個值或沒有任何值。
- ExactlyOne - 必須有一個值。
- ZeroOrMore - 可有一個值、多個值或沒有值。
- OneOrMore - 可有多個值,至少必須有一個值。
參數個數通常可從類型推斷。 例如,int
選項的參數個數為 ExactlyOne
,而 List<int>
選項的參數個數則為 OneOrMore
。
選項覆寫
如果參數個數的最大值為 1,您仍然可以設定 System.CommandLine
接受選項的多個執行個體。 在此情況下,重複選項的最後一個執行個體會覆寫前面所有的執行個體。 下例中的值 2 會傳遞至 myapp
命令。
myapp --delay 3 --message example --delay 2
多個引數
如果參數個數的最大值大於一,您可設定 System.CommandLine
接受一個選項有多個引數,無須重複選項名稱。
以下範例中,傳遞至 myapp
命令的清單會包含 "a"、"b"、"c" 和 "d":
myapp --list a b c --list d
選項統合
POSIX 建議您支援單字元選項的統合,也稱為堆疊。 統合的選項是在單連字號前置詞後,一起指定的單字元選項別名。 只有最後一個選項可以指定引數。 例如,下列命令列有相同的效果:
git clean -f -d -x
git clean -fdx
在選項統合後所提供的引數,會套用至統合中的最後一個選項。 下列命令列有相同的效果:
myapp -a -b -c arg
myapp -abc arg
在此範例的這兩個變體中,引數 arg
只套用至選項 -c
。
布林值選項 (旗標)
如果 true
或 false
針對具有 bool
引數的選項傳遞,則會依預期剖析。 但引數類型為 bool
的選項,通常不需要指定引數。 布林值選項有時稱為「旗標」,其參數個數通常是 ZeroOrOne。 命令列上未後接引數的選項名稱,會產生預設值 true
。 命令列輸入中沒有選項名稱會產生值 false
。 如果 myapp
命令列印出名為 --interactive
的布林選項值,下列輸入會建立下列輸出:
myapp
myapp --interactive
myapp --interactive false
myapp --interactive true
False
True
False
True
--help 選項
命令列應用程式通常會提供選項,以顯示可用命令、選項和引數的簡短描述。 System.CommandLine
會自動產生說明輸出。 例如:
dotnet list --help
Description:
List references or packages of a .NET project.
Usage:
dotnet [options] list [<PROJECT | SOLUTION>] [command]
Arguments:
<PROJECT | SOLUTION> The project or solution file to operate on. If a file is not specified, the command will search the current directory for one.
Options:
-?, -h, --help Show command line help.
Commands:
package List all package references of the project or solution.
reference List all project-to-project references of the project.
應用程式使用者可能習慣在不同的平台上以不同的方式要求說明,因此建置於 System.CommandLine
上的應用程式會回應許多要求說明的方式。 下列命令全都有相同的效果:
dotnet --help
dotnet -h
dotnet /h
dotnet -?
dotnet /?
說明輸出不一定會顯示所有可用的命令、引數和選項。 其中有些可能被隱藏,這表示它們不會顯示在說明輸出中,但可在命令列中指定。
--version 選項
建置在 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
以下是決定如何解譯回應檔文字的語法規則:
- 權杖以空格分隔。 包含 Good morning! 的一行文字視為有兩個權杖:Good 和 morning!。
- 以引號括住的多個權杖會解譯為一個權杖。 包含 "Good morning!" 的一行文字視為有一個權杖:Good morning!。
#
符號和行尾間的任何文字都視為註解並予以忽略。- 前面加上
@
的權杖可以參考其他回應檔。 - 回應檔可有多行文字。 這些文字行會串連並解譯為權杖序列。
指示詞
System.CommandLine
引入了稱為指示詞的語法元素。 例如 [parse]
指示詞。 當您在應用程式名稱後面加上 [parse]
時,System.CommandLine
會顯示剖析結果圖,而不是叫用命令列應用程式:
dotnet [parse] build --no-restore --output ./build-output/
^-----^
[ dotnet [ build [ --no-restore <True> ] [ --output <./build-output/> ] ] ]
指示詞的目的是提供各命令列應用程式皆適用的交叉功能。 因為指示詞與應用程式本身的語法不同,所以可以提供跨應用程式皆適用的功能。
指示詞必須符合下列語法規則:
- 是命令列中的權杖,接在應用程式名稱之後,但出現任何子命令或選項之前。
- 會以方括弧括住。
- 不包含空格。
無法辨識的指示詞予以忽略,不會造成剖析錯誤。
指示詞可以包含引數,以冒號與指示詞名稱分隔。
下列為內建指示詞:
[parse]
指示詞
使用者和開發人員都覺得,能看見應用程式如何解譯指定的輸入非常實用。 System.CommandLine
應用程式的其中一項預設功能是 [parse]
指示詞,可讓您預覽剖析命令輸入的結果。 例如:
myapp [parse] --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> ]
,!
指出剖析錯誤。int
選項的值not-an-int
無法剖析為預期的類型。!
也會在包含錯誤選項的命令前面加上錯誤旗標:![ myapp...
。 - 針對選項結果
*[ --fgcolor <White> ]
,命令列中未指定選項,因此使用設定的預設值。White
是這個選項的有效值。 星號表示此值為預設值。 ???-->
指向不符合任何應用程式命令或選項的輸入。
[suggest]
指示詞
[suggest]
指示詞可讓您在不知確切命令為何時搜尋命令。
dotnet [suggest] buil
build
build-server
msbuild
設計指引
建議您在設計 CLI 時,遵循下列各節提供的指導。 應用程式預期在命令列中看到什麼,就像 REST API 伺服器預期在 URL 中看到什麼,二者情況相似。 REST API 的一致規則正是其隨時可供用戶端應用程式開發人員使用的倚仗。 同樣地,如果 CLI 設計遵循常見的模式,命令列應用程式的使用者就會有更好的體驗。
CLI 建立之後就很難變更,特別是如果使用者在預期持續執行的指令碼中使用了您的 CLI,就更難變更。 這裡的指導是在 .NET CLI 後所寫就,而且情況不一定如這些指導所述。 我們在不引入重大變更的情況下,一直盡力更新 .NET CLI。 這項工作其中之一就是 .NET 7 中的 dotnet new
新設計。
命令和子命令
如果命令有子命令,則命令的作用應如同區域或子命令的群組識別碼,而不是指定動作。 當您叫用應用程式時,您可以指定群組命令與其下一個子命令。 例如,請嘗試執行 dotnet tool
,您會收到一則錯誤訊息,因為 tool
命令只會識別一組與工具相關的子命令,例如 install
和 list
。 您可以執行 dotnet tool install
,但 dotnet tool
只靠自己不夠完整。
定義協助使用者區域的方式之一,是組織說明輸出。
CLI 中通常會有一個隱含區域。 例如,.NET CLI 中的隱含區域是專案,而 Docker CLI 則是映像。 因此,您可以使用 dotnet build
,卻不包含區域。 請考慮您的 CLI 是否有隱含區域。 如果有,請考慮是否允許使用者可選擇包含或省略它,如同 docker build
和 docker image build
一樣。 如果選擇性地允許使用者鍵入隱含區域,您也會自動完成此命令群組的說明和索引標籤。 定義兩個執行相同作業的命令,以提供使用隱含群組的選擇權。
作為參數的選項
選項應向命令提供參數,而不是指定動作本身。 這是建議的設計原則,雖然 System.CommandLine
不一定遵循 (--help
會顯示說明資訊)。
簡短格式別名
一般建議將定義的簡短格式選項別名數量降到最低。
尤其要避免使用下列與其在 .NET CLI 和其他 .NET 命令列應用程式中之常見用法不同的任一別名:
--interactive
用-i
。此選項會向使用者發出訊號,指出他們可能會收到提示,要輸入命令需要回答的問題。 例如,提示輸入使用者名稱。 您的 CLI 可能會用在指令碼中,因此提示未指定此參數的使用者時請務必小心。
--output
用-o
。有些命令會產生檔案作為執行結果。 建議使用此選項協助決定這些檔案的位置。 如果只建立了一個檔案,此選項應為檔案路徑。 如果建立了許多檔案,此選項應為目錄路徑。
--verbosity
用-v
。命令通常會在主控台上向使用者提供輸出,此選項可用來指定使用者要求的輸出量。 如需詳細資訊,請參閱本文後段的
--verbosity
選項。
有些有常見用法的別名僅限於 .NET CLI。 應用程式的其他選項可以使用這些別名,但請注意可能會混淆。
-c
的--configuration
此選項通常是指具名的組建組態,例如
Debug
或Release
。 您可為組態使用任何想要的名稱,但大部分的工具會預期上述名稱其中之一。 此設定通常會使用對該組態有意義的方式,來設定其他屬性,例如,在建置Debug
組態時執行較少的程式碼最佳化。 如果您的命令有其他作業模式,請考慮此選項。-f
的--framework
此選項可用來選取要執行的單一目標 Framework Moniker (TFM),因此,如果您的 CLI 應用程式會根據所選 TFM 而有不同的行為,建議您支援此旗標。
-p
的--property
如果您的應用程式最終會叫用 MSBuild,使用者通常必須以某種方式自訂該呼叫。 此選項允許您在命令列中提供 MSBuild 屬性,並傳遞至基礎 MSBuild 呼叫。 如果您的應用程式不使用 MSBuild,但需要一組索引鍵/值組,請考慮使用這個相同的選項名稱,以利用使用者的預期。
-r
的--runtime
如果您的應用程式可在不同的執行階段中執行,或具有執行階段特定邏輯,請考慮使用此選項來指定執行階段識別碼。 如果您的應用程式支援 --runtime,請考慮也支援
--os
和--arch
。 這些選項可讓您只指定 RID 的 OS 或架構元件,以在目前的平台決定未指定的組件。 如需詳細資訊,請參閱 dotnet publish。
簡短名稱
請盡可能選擇簡短好拼寫的命令、選項和引數名稱。 例如,如果 class
足夠清楚,就不要選擇命令名稱 classification
。
小寫名稱
只以小寫定義名稱,除非大寫別名能讓命令或選項不區分大小寫。
烤肉串式名稱
使用烤肉串式區隔單字。 例如: --additional-probing-path
。
複數表示
在應用程式中,複數要保持一致。 例如,請不要混合可有多個值的選項的複數和單數名稱 (最大的參數個數大於一):
選項名稱 | 一致性 |
---|---|
--additional-probing-paths 和 --sources |
✔️ |
--additional-probing-path 和 --source |
✔️ |
--additional-probing-paths 和 --source |
❌ |
--additional-probing-path 和 --sources |
❌ |
動詞與名詞
指向動作的命令 (項下沒有子命令) 請使用動詞,不要用名詞,例如:dotnet workload remove
,不要用 dotnet workload removal
。 選項使用名詞,不要用動詞,例如:--configuration
,不要用 --configure
。
--verbosity
選項
System.CommandLine
應用程式通常會提供 --verbosity
選項,指定傳送至主控台的輸出量。 以下是標準的五個設定:
Q[uiet]
M[inimal]
N[ormal]
D[etailed]
Diag[nostic]
這些是標準名稱,但現有的應用程式有時會使用 Silent
取代 Quiet
,用 Trace
、Debug
或 Verbose
取代 Diagnostic
。
每個應用程式都會定義自己的準則,判斷每個層級要顯示的內容。 應用程式一般只需要三個層級:
- Quiet
- 一般
- Diagnostic
如果應用程式不需要五個不同的層級,選項仍應定義相同的五個設定。 在此情況下,Minimal
和 Normal
會產生相同的輸出,而 Detailed
和 Diagnostic
也相同。 這可讓使用者只鍵入其熟悉的內容,並使用最適合的內容。
Quiet
預期主控台上不顯示任何輸出。 不過,如果應用程式提供互動模式,應用程式即應執行下列替代方案之一:
- 指定
--interactive
時,顯示輸入提示,即使--verbosity
是Quiet
也一樣。 - 不允許同時使用
--verbosity Quiet
和--interactive
。
否則,應用程式會等待輸入,卻不告知使用者其等待的內容。 應用程式會顯示已凍結,而使用者不知道應用程式正在等待輸入。
如果定義別名,--verbosity
請使用 -v
,讓 -v
成為 --verbosity Diagnostic
的無引數別名。 --verbosity Quiet
用 -q
。
.NET CLI 和 POSIX 慣例
.NET CLI 不會一直遵循所有 POSIX 慣例。
雙短破折號
.NET CLI 有數個命令會特別實作雙短破折號權杖。 如果是 dotnet run
、dotnet watch
和 dotnet tool run
,--
後面的權杖會傳遞至命令所執行的應用程式。 例如:
dotnet run --project ./myapp.csproj -- --message "Hello world!"
^^
在此範例中,--project
選項會傳遞至 dotnet run
命令,而 --message
選項及其引數則會在執行時,以命令列選項的形式傳遞至 myapp。
將選項傳遞至使用 dotnet run
執行的應用程式,不一定需要 --
權杖。 如果沒有雙短破折號,dotnet run
命令會自動傳遞至正在執行的應用程式,任何套用至 dotnet run
本身或 MSBuild 的選項皆無法辨識。 因為 dotnet run
無法辨識引數和選項,所以下列命令列有相同的效果:
dotnet run -- quotes read --delay 0 --fg-color red
dotnet run quotes read --delay 0 --fg-color red
省略區隔選項和引數的分隔符號
當您要指定單字元選項別名時,.NET CLI 不支援可讓您省略分隔符號的 POSIX 慣例。
使用多個引數但不重複選項名稱
.NET CLI 不接受不用重複選項名稱的一選項多引數方式。
布林選項
在 .NET CLI 中,有些布林選項會在您傳遞 false
時,產生和傳遞 true
一樣的行為。 當實作選項的 .NET CLI 程式碼只檢查有無選項卻忽略值時,就會發生此行為。 例如 dotnet build
命令的 --no-restore
。 傳遞 no-restore false
會跳過還原作業,就和您指定 no-restore true
或 no-restore
時一樣。
烤肉串式
有時候,.NET CLI 不使用烤肉串式的命令、選項或引數名稱。 例如,有個 .NET CLI 選項名為 --additionalprobingpath
,而非 --additional-probing-path
。