语法概述:命令、选项和参数

重要

System.CommandLine 目前为预览版,本文档适用于版本 2.0 beta 5。 某些信息与预发布产品有关,该产品在发布前可能会进行大幅修改。 Microsoft对此处提供的信息不作任何明示或暗示的保证。

本文介绍可识别的 System.CommandLine 命令行语法。 此信息对 .NET 命令行应用(包括 .NET CLI)的用户和开发人员都很有用。

令牌

System.CommandLine 将命令行输入分析为标记,这些 标记是用空格分隔的字符串。 例如,请考虑以下命令行:

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

此输入由dotnet应用程序分析为标记toolinstalldotnet-suggest--global--verbosityquiet

令牌解释为命令、选项或参数。 当前调用的命令行应用会确定如何解释第一个令牌之后的令牌。 下表显示了如何 System.CommandLine 解释前面的示例:

令牌 分析为
tool 子命令
install 子命令
dotnet-suggest 安装命令的参数
--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 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 需要文件夹名称参数。 如果未提供参数,该命令将失败。 若要使选项是必需的,请将其 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
                                  ^-----------^

在没有默认值的情况下定义的参数被视为必需参数。

分析错误

选项和参数具有预期类型,当无法分析值时,将生成错误。 例如,以下命令会出错,因为“静默”不是--verbosity的有效值之一:

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'

对于可以提供多少个值,自变量也是有预期的。 有关自变量 arity 的部分中提供了相关示例。

选项和自变量的顺序

可以在命令行中先提供选项再提供参数,或先提供参数再提供选项。 以下命令等效:

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 不支持自动别名。 必须显式指定每个别名。 命令和选项都公开属性 AliasesOption 具有接受别名作为参数的构造函数,因此可以在单个行中定义具有多个别名的选项:

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 是指定该选项或命令时可以传递的值数。

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 结构来定义 arity,具有以下值:

  • System.CommandLine.ArgumentArity.Zero - 不允许任何值。
  • System.CommandLine.ArgumentArity.ZeroOrOne - 可能有一个值,可能没有值。
  • System.CommandLine.ArgumentArity.ExactlyOne - 必须有一个值。
  • System.CommandLine.ArgumentArity.ZeroOrMore - 可能具有一个值、多个值或没有值。
  • System.CommandLine.ArgumentArity.OneOrMore - 可能有多个值,必须至少有一个值。

可以使用属性 Arity 显式设置 arity,但在大多数情况下不需要。 System.CommandLine 根据参数类型自动确定参数 arity:

参数类型 默认 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

若要允许多个参数而不重复选项名称,请设置为 System.CommandLine.Option.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

布尔选项(标志)

如果为具有true参数的选项传递falsebool,则会按预期对其进行分析。 参数类型为 bool 的选项通常不需要指定参数。 布尔选项(有时称为“标记”)的 arity 通常为 System.CommandLine.ArgumentArity.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 引入了一个名为由类型表示的 指令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 之一是 [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] 指令允许在不知道确切命令时搜索命令。

dotnet [suggest] buil
build
build-server
msbuild

另请参阅