• 不同的命令行风格


    一. 命令行格式简介

    最近计划编写一个命令行解析程序,已知命令行的编写格式比较自由,例如:

    ls -l -a

    ls -la

    ls -l –all

    以上3个命令的用途是完全一致的,都是列出当前目录下所有文件的详细信息,但是写法却有很大差别,如何去解析呢。

    为了做到这一点,有必要系统地去了解一下命令行的格式标准,命令行的一般格式为:

    命令 [选项1] [选项2] [选项2参数] [命令参数]

    下面以命令

    du -h --max-depth 1 /home

    为例,作出概念解释。

    1. 命令

    如示例中的du,命令就是程序的调用名称。

    2. 选项、选项参数、命令参数

    对于程序来说,命令后边的内容都是程序的“参数”,可由程序自行识别解析,并无本质不同。

    但具体而言,又可以把“参数”分为3类:选项、选项参数、命令参数。

    2.1. 选项

    如示例中的-h、--max-depth,选项是一种特殊的程序“参数”,选项由程序提前定义,是固定的,是常量。

    2.2. 选项参数

    如示例中的1,它属于选项--max-depth的值,它相对固定,需要满足程序对应选项规定的范围,如必须为整数。

    2.3. 命令参数

    如示例中的/home,命令参数是程序的执行对象,相对自由。

    二. 命令行的不同风格

    为了区分命令行中的选项、选项参数、命令参数,需要制定一些规则。然而,在实践中,由于缺乏统一的规范,造就了不同的命令行风格。

    1. UNIX/POSIX风格

    Unix风格的命令行中,选项是以连字符“-”开头的单个字符(注意是一个字符,而不是一个单词),称之为短选项。

    如果选项后面不带参数,则这样的选项被称之为模式选项。模式选项可以组合在一起使用。

    例如:

    mycommand -a -b

    如果-a和-b是模式选项,那么就可以合并写为-ab或-ba:

    mycommand -ab

    mycommand -ba

    如果选项带参数,这些参数要紧接在选项后面,可以以空格分开,也可以不以空格分开。

    例如:

    mycommand -p 9002

    mycommand -p9002

    mycommand -p9002可不可以理解为多个选项的合并呢?表面上来看,确实是存在歧义的,具体上来说,由于选项是固定的,则可由程序自行识别这究竟是选项合并,还是选项和选项参数的合并。

    由于使用单个字符作为选项,这就限制了选项范围,如果命令非常复杂,选项可能不够用,并且难以理解。

    2. GNU风格

    GNU风格的命令行中,选项是以“--”开头的一个单词,称之为长选项。

    例如:

    mycommand --verbose。

    如果选项需要带参数,则使用空格或者“=”将参数和选项分开。

    例如:

    mycommand --port 9501

    mycommand --port=9501

    GNU风格避免了UNIX风格的缺陷,尽管不是那么简洁,这也是推荐使用的命令行风格。在实践中,通常会将两种风格结合起来使用。

    3. BSD风格

    和UNIX/POSIX风格相比,其选项使用单个字符,且不带任何前缀。

    例如:

    mycommand a b c

    如果是多个不带参数的选项,也可以组合在一起。

    例如:

    mycommand abc

    如果选项需要带参数,选项参数紧跟在选项后面,可以使用空格分开,也可以不用空格。

    例如:

    mycommand P 9501

    mycommand P9501

    这种风格最简洁,但问题也最多,在不了解的情况下难以区分选项、选项参数、命令参数,我认为是垃圾。

    4. X toolkit风格

    原始的X toolkit风格由X toolkit进行解析,其选项选项是以“-”开头的一个单词,它首先过滤并处理某些选项(-display)然后再把过滤后的命令行传递给应用程序逻辑进行解析。

    例如:

    mycommand -version

    如果选项需要带参数,则选项参数紧跟在这个选项后面,且使用空格分开。

    例如:

    mycommand -port 9501

    5. DOS风格

    其选项是以“/”开头的单个字符。

    例如:

    mycommand /C /D

    选项可以合并。

    例如:

    mycommand /C/D

    如果选项带参数,则选项参数紧跟在选项后边,不使用空格分开。

    例如:

    mycommand /CP/D

    三. 命令行解析

    命令行的解析的核心问题就是如何识别选项、选项参数、命令参数。由于命令行编写非常自由,这就给命令行的解析造成了困难。

    1. 停止扫描选项和选项参数的指示符

    以下面的命令行为例:

    mycommand -a p1 --list 9501 test

    可以认为9501是选项--list的选项参数;

    也可以认为9501是命令参数,即选项--list不带参数。

    这就产生了歧义。实践中,这种情况下可以使用一种称之为“扫描停止符”的标志来避免歧义。

    例如:

    mycommand -a p1 --list -- 9501 test

    “--”是一个指示符,表明停止扫描参数,其后所有部分都是命令参数,而不是选项或选项参数。

    2. 不同命令行风格之间的冲突

    鉴于命令行编写格式的自由性,还有其它各种各样的命令行风格。就已知流行的几种命令行风格而言,已经出现了相互冲突的部分。

    例如:

    mycommand -abc

    mycommand -abc

    以UNIX/POSIX风格来解析,命令行带有3个参数,而以X toolkit风格来解析,则命令行只有一个参数。

    因此,使用通用的规则来解析命令行是不可能实现的。

  • 相关阅读:
    EasyAR使用
    基于微信小程序的校园疫情防控小程序源码
    【信号与系统】相位卷绕以及连续信号的符号表示
    DevOps
    使用 TiDB Dashboard 诊断报告定位问题
    Spring、Spring MVC、Spring boot、Spring Cloud面试题(史上最全面试题,精心整理100家互联网企业,面试必过)
    欢度盛夏,畅享清凉——七月超市营销策略
    Mybatis的collection三层嵌套查询(验证通过)
    PCL ICP精配准(点到点)
    基于springboot+vue的旅游管理系统
  • 原文地址:https://blog.csdn.net/Dancen/article/details/126244907