6

编程小知识之命令行解析

 3 years ago
source link: https://blog.csdn.net/tkokof1/article/details/81037393
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

编程小知识之命令行解析

当前的软件开发中,图形界面已然大行其道,命令行似乎愈加式微,不过在一些场景下,命令行仍然必不可少~

工具链的正常运作往往需要仰仗命令行,各个工具间的“沟通交流”基本都是通过命令行来完成,考虑一下 C 语言中 main 函数的标准定义:

// C
int main(int argc, char* argv[])
{
    // codes ...

    return EXIT_SUCCESS
}

其中的 argc 便是命令行的参数个数, 而 argv 则是各个具体的命令行参数~

当我们编写支持命令行的程序时,很多时候都不太在意用以解析命令行的相关逻辑,往往随手写些分支代码便了事了,就像这样(以 C# 代码举例):

// C#
public static void Main(string[] args)
{
    if (args.Length > 0)
    {
        if (args[0] == "-a0")
        {
            OnArg0();
        }
        else if (args[0] == "-a1")
        {
            OnArg1(Convert.ToInt32(args[1]));
        }

        // other situations here ...
    }
}

代码很简单,但其中的问题也很明显:

1. 无法处理复合的命令行参数,譬如 “-a0 -a1 100” 2. 处理非字符串参数较为繁琐,代码中需要在各处书写转换逻辑 3. 各种异常难以处理,譬如转换失败、参数错误等等

复合命令行参数的问题我们可以使用循环来解决:

// C#
public static void Main(string[] args)
{
    int index = 0;
    while (index < args.Length)
    {
        if (args[index] == "-a0")
        {
            OnArg0();
            ++index;
        }
        else if (args[index] == "-a1")
        {
            OnArg1(Convert.ToInt32(args[index + 1]));
            index += 2;
        }
        else
        {
            ++index;
        }

        // other situations here ...
    }
}

但是对于另外两个问题我们还要继续寻找解决方法~

其实解析命令行的更好方式还是使用通用逻辑单独处理,而不要使其耦合于业务逻辑之中,为此我们可以编写一个类库,封装相关解析逻辑~

秉持”最小化”接口原则,对于这个命令行解析库,我个人觉得至少要提供下面3个接口:

// add argument handler
void Add(string name, Action handler);

// remove argument handler
void Remove(string name);

// handle arguments
void Handle(string[] args);

Add接口用于添加某个命令行参数的处理函数

Remove接口则用于去除某个命令行参数的处理函数

Handle接口则是进行实际的命令行解析操作,并执行对应的命令行处理函数

有时候我们可能需要解析原始字符串,而不是分割好的参数列表,为此我们可以提供一个重载的Handle接口:

// handle raw arguments
void Handle(string rawArgs);

github上自己简单搞了一个解析库SimpleArgument,有兴趣的朋友可以看看,欢迎 pr ~

有了辅助库,命令行解析便不再恼人了,之前的代码我们可以改写成这样:

// C#
public static void Main(string[] args)
{
    var sa = new SimpleArgument();
    sa.Add("-a0", OnArg0);
    sa.Add<int>("-a1", OnArg1);

    sa.Handle(args);
    // or we can parse raw args directly
    //sa.Handle("-a0 -a1 100");
}

代码简洁明了,比起之前那些交织的分支(循环)要好上不少~

编程已经足够复杂了,一些机械的、枯燥的(往往也是容易出错的)逻辑就交给类库(或者说自动化)去解决吧~

注 : 点击这里了解SimpleArgument


Recommend

  • 43
    • blog.51cto.com 6 years ago
    • Cache

    3.2 命令行-静心对待知识

    所谓命令行,我们这里指的是基于文本的界面,这个界面允许你输入命令,执行命令并查看运行结果。你能运行一个终端(图形桌面上的字符界面或图形界面之外的文本控制台自身)和嵌入其中的一个命令解释器(Shell)。3.2.1 如何进入命令行当你的系统正常启动后,进入命...

  • 38

    本书全面的介绍了Linux命令行和shell 命令,并且提供了很多的时间教程和实例应用程序信息,为学习的内容提供了相关环境,是Linux 的爱好者以及Linux 系统管理员的首选!..

  • 63
    • www.tuicool.com 5 years ago
    • Cache

    GO学习笔记 - 命令行解析

    image 本文主题:基于os.Args与flag实现Golang命令行解析。 小慢哥的原创文章,欢迎转载...

  • 63

    本篇文章是 Go 标准库 flag 包的快速上手篇。 概述 开发一个命令行工具,视复杂程度,一般要选择一个合适的命令行解析库,简单的需求用 Go 标准库 flag 就够了,flag 的使用非常简单。 当然,除了标准库 fl...

  • 34

    上篇文章 介绍了 flag 中如何扩展一个新的类型支持。本篇介绍如何使用 flag 实现子命令,总的来说,这篇才是这个系列的核心,前两篇只是铺垫。

  • 8
    • blog.studygolang.com 3 years ago
    • Cache

    标准库—命令行参数解析flag

    标准库—命令行参数解析flag 标准库—命令行参数解析flag 评论有人提到没有例子,不知道讲的是什么。因此,为了大家能够更好地理解,特意加了一个示例。其实本文更多讲解的是 flag 的实现原理,加上示例之后,就更好地知道...

  • 3

    Linux命令行与Shell脚本编程大全是一本不可多得的好书,值得多次精读并非常适合作手头工具书。下面是多次阅读的一些摘录整理,方便定期回顾查阅。 第一部分 Linux命令行第一章 初始Linux Shell1 Linux...

  • 2

    如何在 Bash shell 脚本中解析命令行选项 | Linux 中国给你的 shell 脚本添加选项。来源:https://linux.cn/article-13730-...

  • 4

    Python 有没有更好用的第三方命令行解析库?V2EX = way to explore V2EX 是一个关于分享和探索的地方

  • 6

    Linux 命令行与 shell 脚本编程大全 Linux 命令行与 shell 脚本编程大全 shell linux posted on 22 Oct 2020 under category note 文中的示例代码, 如果有命令提示符 $...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK