我的编程空间,编程开发者的网络收藏夹
学习永远不晚

命令行工具开发:如何快速实现命令行提示?

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

命令行工具开发:如何快速实现命令行提示?

不少同学喜欢开发命令行工具,主要是开发快捷,而且和其他命令行工具配合,借助脚本,非常容易实现一些任务的自动化。命令行工具开发比较简单,以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

 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

命令行工具开发:如何快速实现命令行提示?

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

命令行工具开发:如何快速实现命令行提示?

对于稍微复杂一些的命令行工具,命令行的提示功能必不可少。那么对于不同语言的开发者,有没有一种简单快捷的实现方式呢?本文分享一种快速实现的方法,使用YAML文件定义命令行工具的使用规范,再通过工具自动生成各种shell的命令行提示脚本,最后分

如何用Plumbum开发Python命令行工具

如何用Plumbum开发Python命令行工具,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。主要介绍如何使用 Plumbum CLI 工具包来开发 Python 命令行应用程序
2023-06-17

详解Node.js如何开发命令行工具

前言 Node 给前端开发带来了很大的改变,促进了前端开发的自动化,我们可以简化开发工作,然后利用各种工具包生成生产环境。如运行sass src/sass/main.scss dist/css/main.css即可编译 Sass 文件。 在
2022-06-04

使用Rust开发命令行工具

生成二进制文件,将其扔到环境变量的path下即可~ 用rust打造实时天气命令行工具[1] 找到合适的API 使用该api[2] 如请求 api.openweathermap.org/da
2023-08-30

通过Golang实现linux命令ls命令(命令行工具构建)

这篇文章主要为大家详细介绍了如何通过Golang实现一个linux命令ls命令(命令行工具构建),文中的示例代码讲解详细,具有一定的学习价值,感兴趣的可以了解一下
2023-01-13

Node.js怎么实现命令行工具

这篇“Node.js怎么实现命令行工具”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Node.js怎么实现命令行工具”文章吧
2023-07-04

windows命令行工具如何启动

要启动Windows命令行工具(也称为命令提示符或CMD),您可以按照以下步骤操作:1. 打开开始菜单:点击屏幕左下角的Windows徽标图标。2. 搜索:在开始菜单的搜索栏中,键入"cmd"或"命令提示符"。3. 选择命令提示符:从搜索结
2023-09-20

如何从 MySQL 命令行工具返回到 Windows 命令 shell?

EXIT 或 QUIT 命令使您从 MySQL 命令行工具返回到 Windows。mysql> EXIT或者mysql> QUIT
2023-10-22

SCA命令行工具怎样快速构建FaaS服务

这期内容当中小编将会给大家带来有关SCA命令行工具怎样快速构建FaaS服务,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Serverless 架构(无服务器架构),是云计算时代一种全新的、革命性的架构模式
2023-06-05

python开发简单的命令行工具简介

这篇文章主要介绍了python开发简单的命令行工具实例的相关资料,需要的朋友可以参考下
2023-02-01

Go的命令行工具开发:使用Cobra库

通过Go语言和Cobra库,我们不仅可以快速地开发出功能强大的命令行工具,还可以享受到高度自动化和丰富文档的便利。这也是为什么Go和Cobra在命令行工具开发中如此受欢迎的原因。​

如何安装git的命令行工具

安装Git的命令行工具Git是一个常用的版本控制工具,它让开发人员能够更好地管理代码和代码修改历史。为了使用Git,需要安装命令行工具。本文将介绍安装Git命令行工具的方法。下载Git首先,需要从Git官方网站上下载Git安装文件。打开网站
2023-10-22

Ubuntu如何修改命令行提示符

今天小编给大家分享一下Ubuntu如何修改命令行提示符的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1.更改ps1环境变量,
2023-07-04

Netsh.exe工具和命令行开关的示例分析

这篇文章主要为大家展示了“Netsh.exe工具和命令行开关的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Netsh.exe工具和命令行开关的示例分析”这篇文章吧。使用 Netsh.e
2023-06-08

如何实现一个在vbs运行命令行工具后让命令窗口保持打开状态的脚本

这篇文章给大家分享的是有关如何实现一个在vbs运行命令行工具后让命令窗口保持打开状态的脚本的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。问: 如何在运行像 Ping 或 Ipconfig 这样的工具后让命令窗口保
2023-06-08

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录