【问题标题】:Suggestions for implementation of a command line interface命令行界面的实现建议
【发布时间】:2023-04-06 14:15:02
【问题描述】:

我正在重新设计一个命令行应用程序,并正在寻找一种使其使用更加直观的方法。传递到命令行应用程序的参数格式是否有任何约定?或者其他人们发现有用的方法?

【问题讨论】:

  • 了解您的目标环境可能会有所帮助。

标签: command-line user-interface


【解决方案1】:

我看到了很多 Windows 命令行细节,但如果你的程序是为 Linux 设计的,我发现GNU command line standard 是最直观的。基本上,它对命令的长形式(例如,--help)使用双连字符,对短版本(例如,-h)使用单个连字符。您还可以将短版本“堆叠”在一起(例如,tar -zxvf filename)并根据自己的喜好混合长短匹配。

GNU 站点还列出了standard option names

getopt library 极大地简化了这些命令的解析。如果 C 不是你的包,Python 有一个类似的库,Perl 也有。

【讨论】:

  • 对于 Windows,事实上的标准是使用/foo(但也支持-foo,BSD 风格)用于无参数开关,/foo:value(同样,替代-foo:falue)用于那些有参数的。换言之,所有 Microsoft 命令行工具(Win32 开箱即用、开发工具等)使用的语法。
  • 在 Python 中,使用 optparse - docs.python.org/library/optparse.html - 它比 getopt 好用很多
  • @dbr,optparse 现在已被弃用,取而代之的是 docs.python.org/library/argparse.html
  • 术语“捆绑”可能比“堆叠”更常见于描述将空头期权组合在一起的做法
【解决方案2】:

如果您使用 C#,请尝试Mono.GetOptions,它是一个非常强大且易于使用的命令行参数解析器。它适用于 Mono 环境和 Microsoft .NET Framework。

编辑:这里有一些功能

  • 每个参数有 2 个 CLI 表示(1 个字符和字符串,例如 -a 或 --add)
  • 默认值
  • 强类型
  • 自动生成带有说明的帮助屏幕
  • 自动生成版本和版权屏幕

【讨论】:

【解决方案3】:

我喜欢某些 CLI 的一点是快捷方式的使用。
即,以下所有行都在做同样的事情

myCli.exe describe someThing
myCli.exe descr someThing
myCli.exe desc someThing

这样,用户可能不必每次都键入 all 命令。

【讨论】:

  • 这种方法对于 Darcs、Git 和 Subversion 等工具特别有用,它们本质上是一套相关但不同的命令。
  • 没错!除了我将该功能用于另一个版本控制 CLI:ClearCase 的 cleartool (ct) ;)。因为我还管理 Subversion 存储库,所以我会使用 svn 和 svnadmin 命令...
【解决方案4】:

一个很好的有用的参考:

https://commandline.codeplex.com/

可通过 NuGet 获得的库:

  1. 最新稳定版:Install-Package CommandLineParser
  2. 最新版本:Install-Package CommandLineParser -pre

使用默认单例进行一行解析:CommandLine.Parser.Default.ParseArguments(...)
一行帮助屏幕生成器:HelpText.AutoBuild(...).
将命令行参数映射到IList<string>、数组、枚举或标准标量类型。
插件友好的架构,如此处所述。
将动词命令定义为git commit -a
使用 lambda 表达式创建解析器实例。

快速入门:https://commandline.codeplex.com/wikipage?title=Quickstart&referringTitle=Documentation

// Define a class to receive parsed values
class Options {
  [Option('r', "read", Required = true,
    HelpText = "Input file to be processed.")]
  public string InputFile { get; set; }

  [Option('v', "verbose", DefaultValue = true,
    HelpText = "Prints all messages to standard output.")]
  public bool Verbose { get; set; }

  [ParserState]
  public IParserState LastParserState { get; set; }

  [HelpOption]
  public string GetUsage() {
    return HelpText.AutoBuild(this,
      (HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current));
  }
}

// Consume them
static void Main(string[] args) {
  var options = new Options();
  if (CommandLine.Parser.Default.ParseArguments(args, options)) {
    // Values are available here
    if (options.Verbose) Console.WriteLine("Filename: {0}", options.InputFile);
  }
}

【讨论】:

  • 这个命令行解析器有一个new home
【解决方案5】:

如果可以,最好不要假设任何事情。当操作员键入要执行的应用程序名称并且没有任何参数时,可以使用 USAGE 块或替代方法打开 Windows 窗体并允许他们输入您需要的所有内容。

c:\>FOO

FOO

USAGE FOO -{Option}{Value}

-A Do A stuff
-B Do B stuff

c:\>

参数定界我放在宗教主题的标题下:连字符(破折号)、双连字符、斜线、无、位置等。

您没有指明您的平台,但对于下一条评论,我将假设 Windows 和 .net

您可以在 .net 中创建一个基于控制台的应用程序,并允许它使用 Forms 与桌面交互,只需选择基于控制台的项目,然后添加 Windows.Forms、System.Drawing 等 DLL。

我们一直这样做。这样可以确保没有人会在黑暗的小巷中转弯。

【讨论】:

    【解决方案6】:

    命令行约定因操作系统而异,但可能得到最多使用和最公开审查的约定是 GNU getopt 包支持的约定。有关更多信息,请参阅http://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html

    它允许您将单字母命令(例如 -nr)与更长的自记录选项(例如 --numeric --reverse)混合使用。友善点,并实施 --help (-?) 选项,然后您的用户将能够弄清楚他们需要知道的所有内容。

    【讨论】:

      【解决方案7】:

      这是一篇可能对您有所帮助的 CodeProject 文章...

      C#/.NET Command Line Arguments Parser

      如果 VB 是你的口味,这里有一篇单独的文章(包含更多指导相关内容)来查看...

      Parse and Validate Command Line Parameters with VB.NET

      【讨论】:

      • 我看过了。好像太简单了。
      【解决方案8】:

      补充@vonc 的答案,不要接受模棱两可的缩写。例如:

        myCli.exe describe someThing
        myCli.exe destroy someThing
        myCli.exe des someThing ???
      

      事实上,在那种情况下,我可能不会接受“destroy”的缩写......

      【讨论】:

      • 好点,消歧是另一个需要考虑的标准...... +1 给你,先生。
      【解决方案9】:

      我总是加 /?参数来获得帮助,我总是尝试使用默认(即最常见的场景)实现。

      否则,我倾向于将“/x”用于开关,将“/x:value”用于需要传递值的开关。使用正则表达式解析参数变得非常容易。

      【讨论】:

        【解决方案10】:

        我开发了这个框架,也许它有帮助:

        SysCommand 是一个强大的跨平台框架,用于在 .NET 中开发控制台应用程序。简单,类型安全,受 MVC 模式的影响很大。

        https://github.com/juniorgasparotto/SysCommand

        namespace Example.Initialization.Simple
        {
            using SysCommand.ConsoleApp;
        
            public class Program
            {
                public static int Main(string[] args)
                {
                    return App.RunApplication();
                }
            }
        
            // Classes inheriting from `Command` will be automatically found by the system
            // and its public properties and methods will be available for use.
            public class MyCommand : Command
            {
                public void Main(string arg1, int? arg2 = null)
                {
                    if (arg1 != null)
                        this.App.Console.Write(string.Format("Main arg1='{0}'", arg1));
                    if (arg2 != null)
                        this.App.Console.Write(string.Format("Main arg2='{0}'", arg2));
                }
        
                public void MyAction(bool a)
                {
                    this.App.Console.Write(string.Format("MyAction a='{0}'", a));
                }
            }
        }
        

        测试:

        // auto-generate help
        $ my-app.exe help
        
        // method "Main" typed
        $ my-app.exe --arg1 value --arg2 1000
        
        // or without "--arg2"
        $ my-app.exe --arg1 value
        
        // actions support
        $ my-app.exe my-action -a
        

        【讨论】:

          【解决方案11】:

          -operation [参数] -command [你的命令] -anotherthings [otherparams]....

          例如,

          YourApp.exe -file %YourProject.prj% -Secure true
          

          【讨论】:

            【解决方案12】:

            如果您使用生成命令行界面的标准工具之一,例如 getopts,那么您将自动符合要求。

            【讨论】:

              【解决方案13】:

              您用于应用程序的约定取决于

              1) 它是什么类型的应用程序。 2) 您使用的是什么操作系统。

              这绝对是真的。我不确定 dos-prompt 约定,但在类 unix 系统上,一般约定大致如下:

              1) 格式是

              应用名称参数

              2) 单个字符参数(例如'x')作为-x 传递 3)多字符参数(如'add-keys')作为--add-keys传递

              【讨论】:

                【解决方案14】:

                您用于应用程序的约定取决于

                1) 它是什么类型的应用程序。
                2)您使用的是什么操作系统。 Linux?视窗?它们都有不同的约定。

                我的建议是查看系统上其他命令的其他命令行界面,特别注意传递的参数。有不正确的参数应该给用户解决方案指示的错误消息。易于查找的帮助屏幕也有助于提高可用性。

                如果不知道你的应用程序究竟会做什么,很难给出具体的例子。

                【讨论】:

                • 为什么我是为 Linux 还是为 Windows 写作很重要?我认为两者之间应该有一个通用的标准格式。如果您对此有更多见解并愿意分享,请告诉我。
                • 这很重要,因为这两个操作系统做事不同。在命令行应用程序的参数示例中,linux 使用 - 而 windows 使用 / 来指定开关。 ls -l 在 unix 中,dir /ah 用于 Windows。挑一个区别。
                • @lillq 也许两者之间应该有共享格式,但没有。
                【解决方案15】:

                如果您使用 Perl,我的 CLI::Application 框架可能正是您所需要的。它使您可以轻松地构建具有类似 SVN/CVS/GIT 用户界面的应用程序(“your-command -o --long-opt some-action-to-execute some parameters”)。

                【讨论】:

                  【解决方案16】:

                  我创建了一个包含命令行解析器的 .Net C# 库。您只需要创建一个继承自 CmdLineObject 类的类,调用 Initialize,它就会自动填充属性。它可以处理不同类型的转换(使用项目中也包含的高级转换库)、数组、命令行别名、单击一次参数等。它甚至可以自动创建命令行帮助 (/?)。

                  如果您有兴趣,该项目的 URL 是http://bizark.codeplex.com。它目前仅作为源代码提供。

                  【讨论】:

                    【解决方案17】:

                    我刚刚发布了一个更好的命令行解析器。
                    https://github.com/gene-l-thomas/coptions
                    它在 nuget Install-Package coptions

                    using System;
                    using System.Collections.Generic;
                    using coptions;
                    
                    [ApplicationInfo(Help = "This program does something useful.")]
                    public class Options
                    {
                        [Flag('s', "silent", Help = "Produce no output.")]
                        public bool Silent;
                    
                        [Option('n', "name", "NAME", Help = "Name of user.")]
                        public string Name
                        {
                            get { return _name;  }
                            set { if (String.IsNullOrWhiteSpace(value))
                                    throw new InvalidOptionValueException("Name must not be blank");
                                  _name = value;
                            }
                        }
                        private string _name;
                    
                        [Option("size", Help = "Size to output.")]
                        public int Size = 3;
                    
                        [Option('i', "ignore", "FILENAME", Help = "Files to ignore.")]
                        public List<string> Ignore;
                    
                        [Flag('v', "verbose", Help = "Increase the amount of output.")]
                        public int Verbose = 1;
                    
                        [Value("OUT", Help = "Output file.")]
                        public string OutputFile;
                    
                        [Value("INPUT", Help = "Input files.")]
                        public List<string> InputFiles;
                    }
                    
                    namespace coptions.ReadmeExample
                    {
                        class Program
                        {
                            static int Main(string[] args)
                            {
                                try
                                {
                                    Options opt = CliParser.Parse<Options>(args);
                    
                                    Console.WriteLine(opt.Silent);
                                    Console.WriteLine(opt.OutputFile);
                                    return 0;
                                }
                                catch (CliParserExit)
                                {
                                    // --help
                                    return 0;
                    
                                } catch (Exception e)
                                {
                                    // unknown options etc...
                                    Console.Error.WriteLine("Fatal Error: " + e.Message);
                                    return 1;
                                }
                            }
                        }
                    }
                    

                    支持自动 --help 生成,动词,例如命令.exe
                    享受吧。

                    【讨论】:

                    • 您的链接已损坏。所以没有随附的文件。顺便说一句,你的库似乎是gsscoder command line parser的克隆...
                    • 我查看了command lineclipr,然后才考虑编写任何代码,因为它们都使用注释。我已经大大扩展了剪辑器,其代码质量更好,API 更整洁,但最终使用了明智的命名 [Option] 和 [Value],添加了与用户不同的 [Flag](无价值)。我现在添加了对填充字段(更少输入)、/windows 和 -x11 样式选项的支持。并解析 .ini 文件。链接将是github.com/GeneThomas/coptions
                    猜你喜欢
                    • 2010-09-26
                    • 2021-06-26
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-07-21
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多