不少同学喜欢开发命令行工具,主要是开发快捷,而且和其他命令行工具配合,借助脚本,非常容易实现一些任务的自动化。命令行工具开发比较简单,以Java举一个例子,通常我们只需要一个命令行参数解析器,如Java,就有args4j, jopt,picocli等,转换为结构化的对象,根据输入的参数进行相关的逻辑判断,完成对应的逻辑。其他如Node.js, Deno, Python等,也是一样的流程,都有命令行参数解析器,然后基于命令行输入执行对应的逻辑。

一  命令行提示

如果命令行工具稍微复杂一些,那么必须要提供对应的命令行提示,不然开发者几乎没法使用。举一个例子,阿里云有对应的命令行工具aliyun-cli[1],下载安装后就可以使用aliyun命令行工具了。执行 aliyun --help,会发现非常多的子命令,如果没有命令行工具提示,开发者使用这个工具就非常复杂,要去查文档,或者通过命令行的help来输入命令。

aliyun的命令行工具也提供了对应的代码提示,如下所示:

这个命令行提示还不错,你只需要选择对应的子命令然后再进行提示就可以了。

大多数开发者喜欢带描述的命令行提示。并不是所有的子命令和命令参数都命名得非常好,如aliyun命令行给出的live子命令提示,大家可能完全不知道这个live是什么(当然,作为阿里云的同学,我还是知道的, live是视频直播)。而像如下包括描述的命令行提示就直观很多:

二  生成命令行提示

这里不再介绍bash,zsh,fish等各种shell的命令行提示的机制,没有人会手动编写这些命令行提示脚本,大家都会使用框架生成对应shell的命令行提示脚本。

我找了一些命令行解析框架,并且能自动生成命令行提示的,如Java的picocli,Node.js的commander.js,Python的argparse,以及Rust的clap-rs等。我都尝试了一下,最终发现还是clap-rs生成的命令行提示比较好,就是我说的那种带描述,而且还有文件名和目录自动提示,枚举值的提示等,关键是也非常简单。如果有同学有更好的命令行解析框架,希望能留言分享一下。

那么如何让其他语言,如Node.js,Java,Python这些语言编写的命令行工具也能实现和clap-rs的命令行提示一样的效果呢?

三  clap-rs的命令行YAML文件

clap-rs包含了一个命令行工具的YAML规范。我们都知道命令行工具交互比较简单,主要就两个部分:参数和子命令。你看到类似 --conf xxx.yaml 这些带参数名的都属于参数,也可以省略参数名,如 convert a.jpg a.png 其中的a.jpg和a.png也都是参数。子命令就比较容易理解了,我们每天使用的git就是大量使用子命令的,如 git add xxx.jpg 这些。当子命令还可以继续套用子命令,子命令同时也拥有自己的参数。

基于命令行这样的特性,我们完全可以将命令行工具的使用规范通过YAML描述出来,现在一切皆可YAML。

这里我给出一个阿里云命令行工具的YAML定义,当然只是demo。如下:

name: aliyun2

version: "0.1.0"

about: "cli for Alibaba Cloud"

args:

  - version:

      short: v

      long: version

      takes_value: false

      about: Display version

subcommands:

  - oss:

      about: 对象存储

      subcommands:

        - cat:

            about: cat文本文件

            args:

              - file:

                  takes_value: true

                  required: true

                  about: 文件名称

        - ls:

            about: list文件

  - ecs:

      about: 云服务器

      subcommands:

        - SendFile:

            about: send file

        - AddTags:

            about: add tags

可以看出,我首先定义了两个子命令:oss和ecs,然后oss子命令下我又定义了两个子命令:cat和ls。对于oss的cat子命令,我又添加了file这个参数,这样我就可以使用cat来查看oss上文本文件的内容。

有了这个命令行工具YAML规范定义后,我就可以调用clap-rs提供的命令行工具接口,生成对应的shell的提示脚本。效果如下:

这个命令行提示的效果是不是比原先的要好多了?提示有了描述,选择子命令和参数的时候就简单多了。

四  为所有命令行工具写YAML

讲到这里,相信大家都明白了。无论这个工具是Java,Python,Node.js还是Rust编写的,首先定义好该工具的YAML规范,接下来开发人员根据该规范去编写代码,他可以选择他喜欢的语言,他喜欢的命令行解析器,然后实现对应的功能即可。没有代码提升,编写YAML文件不出错是非常难的,所以我做了一个JSON Schema[2]文件,在编写YAML文件时可以进行代码提示,做到编写命令行YAML规范文件更加简单。JSON Schema的使用方法如下:

接下来我们会基于该YAML文件,为各种shell生成对应的命令行提示脚本,如bash,zsh,fish和powershell,这样分开后,开发人员也不需要去处理那些他不清楚的命令行提示,或者找该编程语言对应的SDK来做命令行代码提示。如果没有怎么办?即便有了,生成的提示非常简单怎么办?毕竟命令行工具提示非常重要。

相信Node.js的开发者也不希望还要学习一下Rust和clap-rs,这样就太不高效了。因此我又编写了一个工具cli-completion[3],  其主要目的根据上面说的YAML文件帮你自动生成各种shell的命令行提示脚本。来看一下zsh的例子:

$ cli-completion --zsh commands/aliyun2.yaml > /usr/local/share/zsh/site-functions/_aliyun2

$ autoload -U compinit && compinit

再看一下oh-my-zsh的例子:

$ mkdir ~/.oh-my-zsh/custom/plugins/aliyun2 

$ cli-completion --zsh aliyun2.yaml >  ~/.oh-my-zsh/custom/plugins/aliyun2/_aliyun2

通过这种方式,cli-completion可以为任何命令提供命令行提示。也就是说,以后,你只要编写命令行逻辑,关于命令行提示的问题,全部交给cli-completion帮你生成即可。当然考虑到用户体验,你可能需要在命令行工具中,将cli-completion生成的脚本,通过某一子命令,快速同步到客户端环境。

命令行的开发流程:YAML规范编写,命令行提示自动生成,开发人员下班前完成功能实现。

有同学可能会问,我能否基于YAML文件,并结合某一命令行解析框架,自动完成整个应用的骨架生成,这完全可以,开发人员只要实现一些函数即可,开发会更简单。我个人认为使用PicoCli这些框架自动生成代码,是完全没有问题的。

五  将cli-completion FaaS化

这个功能大家一年都未必用上两次,费时安装也挺麻烦的。现在不是到处都是FaaS,我们也可以尝试一下。首先cli-completion是用Rust编写的,所以可以用传统的方式编写Rust Cloud Lambda,然后部署到云服务上,另外也可以写一个Rust Web应用,如用actix-web,也非常简单。

这些都不够时髦,我们打算将cli-completion的代码WebAssembly化,然后以FaaS方式部署,这里我选择CloudFlare作为FaaS的运行平台。让我们来看一下Demo。

创建一个cli.yaml文件,如下:

name: cli1

version: "0.1.0"

about: "CLI completion for bash, zsh, fish and powershell."

args:

  - help:

      short: h

      long: help

      takes_value: false

      about: Display this help

然后调用cli-completion的FaaS服务,就可以得到对应的命令行提示脚本代码。命令如下:

curl -H 'Content-Type: application/x-yaml' --data-binary "@cli.yaml" https://cli-completion.linux-china.workers.dev/completion/zsh

对比传统的cloud lambda或者cloud function,这种方式FaaS响应速度最快,这种服务调用次数非常少,基本就是每次请求都是冷启动,而WebAssembly这方面就非常有优势。

当然还有一个最大的原因:就是WebAssembly方式的FaaS,它最便宜。

题外话探讨一下cloudflare的WebAssmebly的实现,纯技术讨论,代码如下:

async function handleRequest(request) {

    const { greet } = wasm_bindgen

    await wasm_bindgen(wasm)

    const greeting = greet()

    return new Response(greeting, {status: 200})

}

上述代码中,wasm是一个WebAssembly.Module对象,它是从外部注入的,而不是开发者写的,是FaaS生成的。接下来就是从wasm_bindgen这个函数中获取wasm的导出函数,然后调用 wasm_bindgen(wasm) 将greet函数和wasm module中的export函数进行关联,然后调用greet就会转到wasm module的调用。如果是这样的话,WebAssembly.Module其实是可以外部管理的,当有请求时,再和JavaScript的函数进行关联,这样就可以保证WebAssembly的快速响应。

六  总结

以后大家在写命令行工具时,不用再担心代码提示的问题了。在动手开发工具前,写一下YAML文件,整理和厘清一下你的思路,有哪些子命令,有哪些参数等,然后再基于该YAML文件进行开发,使用什么语言都没有关系,最后配合cli-completion完成命令行提示,你的命令行工具算是相当专业的了,至少从面子上看起来是的 :)

最后列出一些命令行应用涉及的至关重要的命令行解析器,方便大家后续参考:

Java:Picocli, JCommander, JOpt, kotlinx-cli, JLine, args4j

Node.js:Commander.js, clap.js, minimist, yargs[4]

Deno:yargs

Python:argparse, docopt, cli-args, clap

Golang:argparse, flaggy

Rust:clap-rs, pico-args, paw

Ruby:cmdparse, commander, GLI

C++:gflags, cli, docopt.cpp

整理的不全,欢迎大家补充 :)

相关链接

[1]https://github.com/aliyun/aliyun-cli

[2]https://github.com/linux-china/cli-completion/blob/master/cli-schema.json

[3]https://crates.io/crates/cli-completion

[4]https://www.npmjs.com/search?q=args%20parser

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

热门产品

劳务公司运营资料:人力农民工县分公司运营资料|劳务公司运营资料,劳务,公司,运营,资料,人力,农民工,分公司
劳务公司运营资料:人力农民工县分公司运营资料
高职单招合作协议书|高职单招合作协议,高职单招合作协议书,高职合作协议,单招合作协议,高职单招合作合同,高职,单招,合作,协议书
高职单招合作协议书
门窗建材销售技巧和话术 48招|门窗建材销售技巧,门窗建材销售话术,建材销售技巧,建材销售话术,门窗,建材,销售,技巧,话术 48招
门窗建材销售技巧和话术 48招
美容院销售技巧|美容院销售技巧,美容院,销售,技巧
美容院销售技巧
贷款话术以及顾客常见问题|贷款话术,贷款问答话术,贷款问题话术,贷款,话术,以及,顾客,常见问题
贷款话术以及顾客常见问题
聊天话术技巧:不会和客户聊天,教你10个高效沟通技巧!|聊天话术技巧,聊天话术,高效沟通技巧,高效沟通话术,聊天,话术,技巧,不会,客户,教你10个,高效,沟通
聊天话术技巧:不会和客户聊天,教你10个高效沟通技巧!
要成功,学话术!美容师话术参考大全|美容师话术,美容师话术大全,美业话术,美业话术资料,美业话术大全,美业话术手册,成功,学话,美容师,话术,参考,大全
要成功,学话术!美容师话术参考大全
72页寿险陌拜行销+23页车险陌拜话术|寿险陌拜行销,车险陌拜话术,寿险话术,车险话术,寿险销售技巧,车险销售技巧,寿险陌拜技巧,车险陌拜技巧,72页,寿险,陌拜,行销,+23页,车险,陌拜话术
72页寿险陌拜行销+23页车险陌拜话术

历史上的今天:05月02日

美容院业绩百万经营秘籍

美容院业绩百万经营秘籍+---01开店之初一开始开店就注定失败的几大原因.doc创业美容院开业的流程.doc开店做生意 坚持 诚信 承担 信心才能立于不败.doc开店必死的六种人.doc想开店您当老板的做好准备了吗?.doc成功开店五步曲,步步为赢!.doc没有经验可以开美容院吗?我开店前的准备.doc+---02开店选址店面选址评估表.doc开会所美容院如何选址的几点见意.doc开美发店该如何选

团队高效沟通的秘密,全在这3点!

众所周知,沟通在一个团队中,起到非常重要的作用。即使所有人都意识到沟通的重要性,但是由于每个人的沟通的能力和技巧不同,在信息传达过程里或多或少会出现词不达意的情况。有人会说,是不是团队氛围好了,沟通起来也就方便了?不如先来回想自己和父母沟通的过程吧,有的家庭氛围其乐融融,即便相互之间熟悉至此,但是你还是有很多事情,很难和父母沟通。同理,不是一个团队氛围好了,沟通协作的效率就一定能提高。偶尔,一个熟

如何制作员工手册

如何制作员工手册如何制作员工手册员工手册的价值1:让新员工工作思路更清晰2:可以系统的复制人才/提升员工人才3:组建团队更容易员工手册设计大纲目录第一篇:集团介绍1:公司介绍2:文化介绍3:机制介绍4:团队介绍第二篇:专业知识1:产品介绍2:产品优势第三篇:业务开发1:销售流程2:如何找客户3:开发客户方法与话术4:如何服务客户5:客户案例6:抗拒解除第四篇:价值补充1:销售十大步骤2:每天做什么

店长岗位说明书

店长岗位说明书店长岗位说明书基本信息岗位名称店长所属部门店面岗位编号直接上级店面经理店    员1所辖人员直接下属店长助理、导购考核方式职等职级薪酬类型底薪+提成职位概述店面管理工作职责权重销售管理1. 按照年度总目标分解指标,完成店面销售指标任务2. 建立销售台账,与各项物料的进出使用记录,每月做出相关分析报表3. 参与产品策略、价格策

【脚本】电器直播脚本

【脚本】电器直播脚本电器直播带货剧本主题:X净水器时间:42分钟人物:主播x2转场:开始主持人A:大家好!对于我们的资深观众来说,知道今天是什么日子,所以会显得更加兴奋些,今天是我们一年一度的快抢节,可以看到在台上的商品,当然对于今天这个节目,出现的品牌是我们反复斟酌而定的,反复推敲过后才带给各位的,对于价格,我们也是特意为今天的观众专程而准备的。主持B:没错。主持人A:话不多说,接下来由我A和B

【脚本】抖音直播带货方案直播脚本(范本)

【脚本】抖音直播带货方案直播脚本(范本)抖音直播带货方案(范本)一、直播主题:爆款一折购二、直播时间:20xx年7月25日(周三)13:00三、直播地点:XXX商业区四、主持人:小E五、嘉宾:XXX六、直播细节1、前期准备在开播前主播提前准备,找个明亮隔音的房间,打扮自我形象,并检查设备,准备开播,开播前项目人员提前准备好项目信息说辞(简明扼要),在开播前项目人员提前进入主播间,2、开场预热首先进

热门专题

一年制中专|中专学历,中专是什么学历,中专是什么,中专有什么专业,中专升大专,一年制中专
一年制中专
中源管业|中源管业,中源管业公司,中源管业有限公司,中源管业电话,中源管业地址,中源管业电力管,中源管业mpp电力管,中源管业cpvc电力管,中源管业pe穿线管
中源管业
卓越综合高中|卓越综合高中
卓越综合高中
大理科技管理学校|大理科技管理中等职业技术学校,大理市科技管理中等职业技术学校
大理科技管理学校
昆明网站建设|昆明网站建设,昆明网站开发,昆明网站建设公司,昆明网站建设价格,昆明网站设计,昆明网站制作,网页设计,高端网站建设,高端网站设计
昆明网站建设
大理科技管理学校|大理科技管理学校,大理科技,大理科技中等职业技术学校,大理科技管理中等职业技术学校,大理科技学校
大理科技管理学校
云南巨榕教育投资集团有限公司|云南巨榕教育投资集团有限公司,巨榕教育集团,巨榕教育
云南巨榕教育投资集团有限公司
弥勒综合高中|弥勒综合高中
弥勒综合高中

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部