当前位置: 首页 > 网络应用技术

命令行分析的新想法(GO语言描述)

时间:2023-03-09 00:19:39 网络应用技术

  简介:本文打破了命令行的固有印象,重新删除了命令行的概念,并开发了一种功能强大但非常简单的命令行分析方法。此方法支持任何数量的子命令,支持可选和可选参数,并为可选参数提供默认值。支持配置文件,环境变量和命令行参数同时,配置文件,环境变量,命令行参数采用有效优先级的顺序,这可能更符合12因子的原理。

  作者|了解来源|ALI技术公共编号

  命令行分析是一项技术,几乎每个后端程序员都将使用,但是与业务逻辑相比,这些精美的分支并不重要。如果您只追求简单需求的满意度,那么处理线就会更简单。程序员可以随手。GO标准库为每个人使用的标志库提供了标志库。

  但是,当我们想使我们的命令行更加丰富时,问题开始变得复杂。例如,我们需要考虑如何处理选项和选项。以及子命令的子命令,如何处理子命令的参数等等。

  目前,GO语言中最广泛使用的命令行分析库是眼镜蛇,但是与标准库的标志相比,丰富的特征使眼镜蛇变得非常复杂。代码生成的功能可以自动生成命令行的骨架。但是,在节省开发时间的同时,它也使代码不直观。

  通过打破命令行的固有印象,本文重新解决了命令行的概念,并开发了一种功能强大但极其简单的命令行解析方法。此方法支持任何数量的子命令,支持可选和可选参数,并为可选参数提供默认值。支持配置文件,环境变量和命令行参数同时,配置文件,环境变量,命令行参数采用有效优先级的顺序,这可能更符合12因子的原理。

  GO标准库标志提供了一种非常简单的命令行解析方法。定义命令行参数后,您只需要调用flag.parse方法。

  可以看出,标志库的使用非常简单。需要命令行参数后,您只需要调用flag.parse即可完成参数的分析。定义命令行参数时,您可以指定默认值和使用此参数的说明。

  如果要处理子命令,标志是无能为力的。目前,您可以选择自己分析子命令,但更直接地使用眼镜蛇库。

  这是眼镜蛇官员演示如何使用此库的示例

  您可以看到添加子命令使代码稍微复杂,但是逻辑仍然很清楚,并且sub -command and命令遵循相同的定义模板。子命令也可以定义其子命令。

  眼镜蛇具有强大的功能和清晰的逻辑,因此每个人都广泛认可它。但是,这里有两个问题使我不满意。尽管问题并不大,但总是伤心欲绝。

  1参数定义和命令逻辑分离

  从上述时间的定义来看,参数的定义与命令逻辑的定义分开(即在此处运行)。当我们有大量的子命令时,我们更倾向于将命令的定义放在不同的文件上。

  当然,使用眼镜蛇也很容易解决这个问题。只要参数定义从主函数转移到init函数,并且init函数分散到sub -command的定义。同一时间定义文件中的init函数,并在函数中定义了时代的参数。但是,当有许多参数时,这会导致大量的全局变量,就像对清晰,简单和非 - 的追求一样。追求代码的副作用。

  为什么不像标志库一样定义命令函数中的参数定义?此代码更紧凑,逻辑更直观。

  我相信每个人都会理解只能通过分析命令行参数来调用时间函数。这需要提前定义命令行参数。如果将参数定义为TimesAnalyAse相关参数,这与根据Shell的颜色转换更改手机的主题一样不合理,但是真的是这样吗?

  2命令和父命令的定义不够灵活

  在开发子命令甚至多个子命令的工具时,我们经常面临一个问题,即是否选择CMD {resource} {action}或cmd {action} {action} {resource},这是资源和动作,谁是谁是参数参数。问题,例如kubernetes的设计,是作为子女命令的动作:kubectl获取豆荚... kubectl得到部署...当动作由于不同的资源而截然不同时,通常会选择资源为儿童司令部,例如阿里巴巴云。CommandLine工具:Aliyun ECS ... Aliyun Ram ...

  在实际的开发过程中,在开始时,我们可能无法确定哪种动作和资源更好,而这些动作和资源更好,而当有多个子命令时,这种选择可能会更加困难。

  当不使用任何库时,开发人员可以选择在父命令中初始化相关资源并在子命令中执行代码逻辑,以便父亲的命令和sub -commands很难互相交换。这实际上是一个错误的逻辑。称为子命令并不意味着必须调用父亲的命令。对于命令行工具,命令执行该进程将撤回。重复使用。

  眼镜蛇的设计使每个人都可以避免此错误逻辑。子命令需要提供运行函数。在此功能中,应实现初始化资源,业务逻辑的执行和破坏资源的整个生命周期。但是,COBRA仍然需要定义父命令,也就是说,必须定义echo命令以定义SUB- 回声时代的命令。实际上,在许多情况下,父亲的命令没有执行逻辑,尤其是以资源为父亲的命令的场景。父亲命令的唯一角色是打印该命令的用法。

  眼镜蛇命令和父亲的命令的定义非常简单,但是父亲-son交换仍然需要修改其之间的链接关系。有没有办法使这个过程更容易?

  关于命令行的术语很多,例如参数,徽标和选项等。COBRA设计基于以下概念定义命令代表动作,ARGS是这些操作的修饰符。

  此外,根据这些定义进行了更多概念,例如持久标志代表适用于所有子命令的标志。本地标志代表当前子命令的标志,所需的标志。

  这些定义是眼镜蛇的核心设计来源。为了解决我上面提到的两个问题,我们需要重新检查这些定义。为此,我们分析了命令行逐步分析。

  1命令行只是可以通过shell解析执行的字符串

  命令行及其参数只是一个字符串。字符串的含义由Shell解释。对于Shell,命令行由命令和参数组成。命令,参数以及参数和参数除以空白符号。

  其他吗?不,没有父订单,子订单,也没有持久参数,本地参数。一个参数是双水平线( - ),单个水平行( - )或其他字符。只是,这些字符串由Shell传递给要执行的程序,并将其放在OS.Args的数组中(GO Language))。

  2个参数,徽标和选项

  从上面的描述中,参数(参数)是命令行背后空白符号的字符串的标题,参数可以在命令行中给出不同的含义。

  从水平或双层线开始的参数看起来有些特别。结合代码,这种类型的参数具有其唯一效果,即将某个值与代码中的某个变量相关联。这种类型的Isparameters,我们称为signs.recall,os.args数组中有许多参数。这些参数与命令中的变量无直接相关,而FLAG提供的本质是键值对。在我们的代码中,通过键的键,与某个具有一定的on eneth变量的键相关联,可以实现分配此变量的功能。

  徽标使我们能够通过命令行分配一个值为代码中的变量的值。然后,一个新问题是,如果我不分配此变量,可以继续运行该程序吗?如果您无法继续运行,此参数(标志只是一个特殊参数)是必须的,否则可用。命令行也可能定义多个变量。任何变量都是有价值的,并且可以执行程序,也就是说,只要在此多个徽标中指定一个程序,就可以执行该程序。该角度可以称为选项。

  在上述分析之后,我们发现参数,标识和选项的概念相互交织在一起,既有差异又具有相似的含义。标识是从水平线开始的参数,标识名称背后的参数(如果是。

  3个子命令

  在上述分析之后,我们可以简单地得出结论,sub -command只是一个特殊参数。该参数与其他参数没有差异(与徽标的前线不同)或函数(可以将任意操作作为函数打包)。

  与标识符和子命令相比,我们将出乎意料地发现关联:徽标关联变量和sub -command相关功能!它们具有相同的目的。徽标背后的参数是变量的值。然后,子命令背后的所有参数是此函数的参数(不是语言级别的功能参数)。

  更有趣的问题是为什么身份证需要从水平线开始?如果没有水平线,它可以实现关联变量的目的吗?这显然还可以,因为子命令没有水平线,并且有本质上,该关联是通过识别或子命令实现的。水平线扮演什么角色?

  它是否与变量或函数关联,并且仍由参数的名称确定。这是代码中预定的。没有水平线可以区分标识符和子命令。

  例如:

  可以看出,识别对核心函数的实现没有特殊影响。水平线的作用主要用于增强可读性。但是,应注意的是,尽管我们基本上不需要识别,但一旦拥有徽标,我们就可以使用其特征来实现其他功能。例如话

  4命令行的组成

  在上述分析之后,我们可以将命令行的参数提供给不同的概念

  让我们重新审查第一个需求,即,我们期望任何子命令的实现,就像使用标准库标志一样简单。这也意味着只有在执行此函数时,请解决命令行参数。可以将子命令与其他参数区分开,然后我们可以先执行子命令的相应函数,然后分析子命令的参数。

  之所以被称为parse的原因是Shell已经知道字符串的第一项是命令本身,所有后续项目都是参数。同样,如果我们可以识别子订单的顺序,那么也可以允许以下代码与以下代码合并:

  问题的关键是如何将子命令与其他参数区分开。标识符从水平或双层线开始。它可能明显不同。其他人则需要分子命令,子命令参数和标识参数。如果我们仔细考虑,我们可以发现,尽管我们期望没有预定的参数,但是可以预先定义子命令。通过比较非标准名称参数,与预定的子命令进行比较,我们可以识别子命令。

  为了演示如何识别子订单,上面的眼镜蛇的代码就是一个示例。假设COBRA.GO代码被编译为程序应用程序,则可以执行命令行

  根据眼镜蛇的概念,时代是Echo的子命令,Echo是应用程序的子命令。我们将Echo Times整体作为一个应用程序。

  1个简单的分析过程

  2励志检测过程

  上述分析相对简单,但实际上,我们通常期望允许标识出现在命令行的任何位置。例如,我们希望为控制打印颜色红色的新选择。从逻辑上讲,颜色选项甚至是由Echo描述的,而不是时间的描述,因此我们希望支持以下命令行:

  目前,我们预计要称呼的提交仍然是回声时间,但是中间参数使情况变得复杂,因为这里的参数红色可能是颜色的信号参数(红色),这可能是SUB的一部分-command,也可能是儿童命令的参数。更重要的是,用户还可以将参数错误编写为-Color Times

  SO值的灵感检测是指解析红色参数时,我们不知道RED命令(或子命令的前缀部分)还是Sub -Command的参数,因此我们可以假设它是子命令的前缀。匹配,如果不匹配,则将其视为sub -command参数。

  您可以看到红色不需要区分它是颜色的徽标参数,还是子命令的非logo参数。只要它与任何子命令不匹配,就可以确认它必须是子命令的参数。

  3个子命令任意编写订单

  子命令本质上是字符串。我们的励志分析已经实现了任意命令字符串的识别,只要此字符串已提前定义。也就是说,将此字符串关联到函数。设计的设计使父命令和子命令只是一个逻辑概念,它没有任何内容,并且没有任何内容与特定的代码实现有关。我们需要做的是调整映射。

  维护映射关系

  为了实现上述想法,我开发了Cortana项目。科尔塔纳(Cortana)介绍了btree之间的映射关系以建立子命令和功能。由于具有前缀的能力,用户可以输入任何子命令前缀,并且该程序将自动列出所有可用的子命令。励志命令行的解析机制可以在分析特定标识或子命令之前分析子命令。参数,以搜索子命令的功能。在映射函数图中,变量的绑定。加法,Cortana充分利用GO语言结构标签的特征,简化了变量绑定过程。

  我们使用Cortana重新实现眼镜蛇代码的功能

  命令用法与眼镜蛇完全相同,但是自动生成生成的自动帮助信息之间存在一些差异

  1个选项和默认值

  可以看出,Echo Times命令具有一个时间徽标,此外,它将显示。内容本质上是命令行参数,并且可以将其分为多个参数,因为内容中有空格。

  我们上面提到的是,标识实质上是将一定值绑定到变量,标识符的名称,例如这里的时间,与变量argss.times相关,因此对于非标准知识的其他参数,这些参数是这些参数是没有名称的,所以我们被绑定到一个切片,即args.texts

  Cortana定义了自己的结构标签,该标签用于指定其长徽标的描述信息,短标准名称,默认值和此选项。格式为:“长,短,默认,描述””。

  为了促进记忆,Cortana的标签名称也可以写为LSDD,这是英语前四部分的前四部分。

  2个子命令和别名

  AddCommond可以添加任何顺从命令,这实际上是子命令的建立与处理功能之间的映射关系。

  在此示例中,打印命令与echo命令相同。实际上,我们实际上可以通过别名将两者关联

  执行打印命令实际执行回声

  别名的机制非常灵活,可以为任何命令和参数设置别名。例如,我们希望实现三个子命令并打印3次字符串。可以直接通过别名实施:

  3帮助标识和命令

  Cortana自动为任何命令生成帮助信息。也可以通过cortana.disablehelpflag或cortana.helpflag设置您喜欢的标识名称。

  Cortana在默认值中不提供帮助subdos命令,但是使用别名机制,我们很容易实现帮助命令。

  4个配置文件和环境变量

  除了通过命令行参数绑定变量外,Cortana还支持用户定义的绑定配置文件和环境变量。Cortana对配置文件或环境变量的分析概不负责。用户可以使用第三方库来满足此需求。Cortana的主要作用是基于根据优先合并的不同来源的价值,其优先顺序如下:

  Cortana旨在促进任何格式的配置。用户只需要实现Unmarshaler界面即可。例如,使用JSON作为配置文件:

  Cortana将配置文件或环境变量的分析完全移交给第三张库。用户可以自由定义如何将配置文件绑定到变量,例如使用jsontag。

  5没有子命令?

  Cortana搜索的设计命令和参数解析解耦,因此两者可以独立使用。例如,在没有子命令的情况下,参数分析直接在主要函数中实现:

  命令行分析是每个人都将使用的函数,但这并不是特别重要。除非它是专注于命令行的使用的工具,否则一般过程无需过分关注命令行的分析。我很感兴趣,并阅读文章的最后一位读者。我表示真诚的感谢。

  旗库简单易用,眼镜蛇的功能丰富,这两个库几乎可以满足我们的所有需求。但是,在编写命令行的过程中,我总是觉得现有的kurome不足。标志库仅解决识别分析问题。尽管眼镜蛇库支持子命令和参数的分析,但sub -commands和参数的解析是耦合的,但参数定义与函数分开。Cortana的核心吸引力是分解命令搜索和参数分析。通过重新整合命令行的线参数的本质,我发明了鼓舞人心的分析方法,并最终实现了上述目标。这使Cortana使Cortana具有相同的COBRA功能,并且具有像Flag这样的经验。我感到非常舒适。通过精美的设计,通过非常简单的机制实现强大的功能体验。我希望通过这篇文章,我可以与您分享我的幸福。