阿里妹导读:对于稍微复杂一些的命令行工具,命令行的提示功能必不可少。那么对于不同语言的开发者,有没有一种简单快捷的实现方式呢?本文分享一种快速实现的方法,使用YAML文件定义命令行工具的使用规范,再通过工具自动生成各种shell的命令行提示脚本,最后分享一些至关重要的命令行解析器。
文末福利:云开发体验——Linux指令入门。
不少同学喜欢开发命令行工具,主要是开发快捷,而且和其他命令行工具配合,借助脚本,非常容易实现一些任务的自动化。命令行工具开发比较简单,以Java举一个例子,通常我们只需要一个命令行参数解析器,如Java,就有args4j, jopt,picocli等,转换为结构化的对象,根据输入的参数进行相关的逻辑判断,完成对应的逻辑。其他如Node.js, Deno, Python等,也是一样的流程,都有命令行参数解析器,然后基于命令行输入执行对应的逻辑。 一 命令行提示 如果命令行工具稍微复杂一些,那么必须要提供对应的命令行提示,不然开发者几乎没法使用。举一个例子,阿里云有对应的命令行工 具aliyun-cli[1], 下载安装后就可以使用aliyun命令行工具了。执行 aliyun --help ,会发现非常多的子命令,如果没有命令行工具提示,开发者使用这个工具就非常复杂,要去查文档,或者通过命令行的help来输入命令。 aliyun的命令行工具也提供了对应的代码提示,如下所示:name: aliyun2version: "0.1.0"about: "cli for Alibaba Cloud"args: - version: short: v long: version takes_value: false about: Display versionsubcommands: - 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的提示脚本。效果如下:
$ 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规范编写,命令行提示自动生成,开发人员下班前完成功能实现。
name: cli1version: "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
云开发体验 Linux指令入门——文件与权限
阿里云开发者成长计划来啦!基于真实的云环境和业务场景,帮助开发者深入学习体验云上技术。本场景将提供一台配置了Aliyun Linux 2的ECS实例(云服务器),介绍Linux系统中常用的文件目录管理和文件权限管理命令。