c# - 在 C# 中使用子命令解析命令行

标签 c# command-line-arguments

<分区>

是否有C#的命令行解析库,对git、svn等风格的“子命令”有很好的支持?例如,“git”命令有几个子命令:

git add
git status
git diff
...

既有全局选项必须在子命令名称之前,也有特定于子命令的选项必须在其名称之后。例如,它们做不同的事情:

git -p add
git add -p

不同的子命令可能各自具有完全不同的选项和参数集。

我一直在使用 NDesk.Options,但直到现在我还不需要实现子命令。我认为它足够灵活,可以在其上构建子命令,但如何以简洁优雅的方式最好地做到这一点并不完全清楚。是否可以在 NDesk.Options 中执行此操作,或者是否有更合适的 C# 命令行解析库?

最佳答案

我偏爱my own option parsing library ,我是 blogging about currently .我确实打算介绍子命令,但我还需要一段时间才能讲到它(这将是最后一篇博文)。

Nito.KitchenSink.OptionParsing 不直接支持子命令,但您可以使用该库仅解析部分命令行,并自行处理子命令。 “global”和“sub-command-specific”选项集增加了一个有趣的转折,但它可以像这样完成:

using System;
using System.Linq;
using Nito.KitchenSink.OptionParsing;

class Program
{
  private sealed class GlobalOptions : OptionArgumentsBase
  {
    // Use a better name than "POption". This is just an example.
    [Option('p', OptionArgument.None)]
    public bool POption { get; set; }

    // Override Validate to allow AdditionalArguments.
    public override void Validate()
    {
    }
  }

  private sealed class AddOptions : OptionArgumentsBase
  {
    [Option('p', OptionArgument.None)]
    public bool POption { get; set; }
  }

  static int Main()
  {
    try
    {
      // Parse the entire command line into a GlobalOptions object.
      var options = OptionParser.Parse<GlobalOptions>();

      // The first entry in AdditionalArguments is our sub-command.
      if (options.AdditionalArguments.Count == 0)
        throw new OptionParsingException("No sub-command specified.");
      object subcommandOptions = null;
      string subcommand = options.AdditionalArguments[0];
      switch (subcommand)
      {
        case "add":
        {
          // Parse the remaining arguments as command-specific options.
          subcommandOptions = OptionParser.Parse<AddOptions>(options.AdditionalArguments.Skip(1));
          break;
        }
        case "status": // TODO: Parse command-specific options for this, too.
          break;
        case "diff": // TODO: Parse command-specific options for this, too.
          break;
        default:
          throw new OptionParsingException("Unknown sub-command: " + subcommand);
      }


      // At this point, we have our global options, subcommand, and subcommand options.
      Console.WriteLine("Global -p option: " + options.POption);
      Console.WriteLine("Subcommand: " + subcommand);
      var addOptions = subcommandOptions as AddOptions;
      if (addOptions != null)
        Console.WriteLine("Add-specific -p option: " + addOptions.POption);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      // TODO: write out usage information.
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}

上面的示例程序产生以下输出:

>CommandLineParsingTest.exe
No sub-command specified.

>CommandLineParsingTest.exe -p
No sub-command specified.

>CommandLineParsingTest.exe test
Unknown sub-command: test

>CommandLineParsingTest.exe add
Global -p option: False
Subcommand: add
Add-specific -p option: False

>CommandLineParsingTest.exe -p add
Global -p option: True
Subcommand: add
Add-specific -p option: False

>CommandLineParsingTest.exe add -p
Global -p option: False
Subcommand: add
Add-specific -p option: True

>CommandLineParsingTest.exe -p add -p
Global -p option: True
Subcommand: add
Add-specific -p option: True

>CommandLineParsingTest.exe status
Global -p option: False
Subcommand: status

>CommandLineParsingTest.exe -p status
Global -p option: True
Subcommand: status

关于c# - 在 C# 中使用子命令解析命令行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6507430/

相关文章:

c# - 使用 EF Code First 控制属性唯一性的最佳方法

c# - 如何将Dictionary <object,object>序列化为json

c# - 安装 net core 后加载 hostfxr.dll 失败

c# - 在 C# 中使用快照时,FFMpegCore 不生成输出

java - 使用 -cp 时传递 Java 命令行参数

c# - 如何使用 epplus 在 excel 中将小数格式化为百分比?

perl - 使用 -n 或 -p 选项时是否可以将命令行参数传递给 @ARGV?

c - 尝试检查命令行参数时出现段错误(在 C 中)

android - 切换 Android 设备数据连接

c - 读取整数