日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

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

發(fā)布時(shí)間:2024/9/3 65 豆豆
生活随笔 收集整理的這篇文章主要介紹了 命令行工具开发:如何快速实现命令行提示? 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
簡(jiǎn)介:對(duì)于稍微復(fù)雜一些的命令行工具,命令行的提示功能必不可少。那么對(duì)于不同語(yǔ)言的開(kāi)發(fā)者,有沒(méi)有一種簡(jiǎn)單快捷的實(shí)現(xiàn)方式呢?本文分享一種快速實(shí)現(xiàn)的方法,使用YAML文件定義命令行工具的使用規(guī)范,再通過(guò)工具自動(dòng)生成各種shell的命令行提示腳本,最后分享一些至關(guān)重要的命令行解析器。

不少同學(xué)喜歡開(kāi)發(fā)命令行工具,主要是開(kāi)發(fā)快捷,而且和其他命令行工具配合,借助腳本,非常容易實(shí)現(xiàn)一些任務(wù)的自動(dòng)化。命令行工具開(kāi)發(fā)比較簡(jiǎn)單,以Java舉一個(gè)例子,通常我們只需要一個(gè)命令行參數(shù)解析器,如Java,就有args4j, jopt,picocli等,轉(zhuǎn)換為結(jié)構(gòu)化的對(duì)象,根據(jù)輸入的參數(shù)進(jìn)行相關(guān)的邏輯判斷,完成對(duì)應(yīng)的邏輯。其他如Node.js, Deno, Python等,也是一樣的流程,都有命令行參數(shù)解析器,然后基于命令行輸入執(zhí)行對(duì)應(yīng)的邏輯。

一 命令行提示

如果命令行工具稍微復(fù)雜一些,那么必須要提供對(duì)應(yīng)的命令行提示,不然開(kāi)發(fā)者幾乎沒(méi)法使用。舉一個(gè)例子,阿里云有對(duì)應(yīng)的命令行工具aliyun-cli[1],下載安裝后就可以使用aliyun命令行工具了。執(zhí)行 aliyun --help,會(huì)發(fā)現(xiàn)非常多的子命令,如果沒(méi)有命令行工具提示,開(kāi)發(fā)者使用這個(gè)工具就非常復(fù)雜,要去查文檔,或者通過(guò)命令行的help來(lái)輸入命令。

aliyun的命令行工具也提供了對(duì)應(yīng)的代碼提示,如下所示:

這個(gè)命令行提示還不錯(cuò),你只需要選擇對(duì)應(yīng)的子命令然后再進(jìn)行提示就可以了。

大多數(shù)開(kāi)發(fā)者喜歡帶描述的命令行提示。并不是所有的子命令和命令參數(shù)都命名得非常好,如aliyun命令行給出的live子命令提示,大家可能完全不知道這個(gè)live是什么(當(dāng)然,作為阿里云的同學(xué),我還是知道的, live是視頻直播)。而像如下包括描述的命令行提示就直觀很多:

二 生成命令行提示

這里不再介紹bash,zsh,fish等各種shell的命令行提示的機(jī)制,沒(méi)有人會(huì)手動(dòng)編寫這些命令行提示腳本,大家都會(huì)使用框架生成對(duì)應(yīng)shell的命令行提示腳本。

我找了一些命令行解析框架,并且能自動(dòng)生成命令行提示的,如Java的picocli,Node.js的commander.js,Python的argparse,以及Rust的clap-rs等。我都嘗試了一下,最終發(fā)現(xiàn)還是clap-rs生成的命令行提示比較好,就是我說(shuō)的那種帶描述,而且還有文件名和目錄自動(dòng)提示,枚舉值的提示等,關(guān)鍵是也非常簡(jiǎn)單。如果有同學(xué)有更好的命令行解析框架,希望能留言分享一下。

那么如何讓其他語(yǔ)言,如Node.js,Java,Python這些語(yǔ)言編寫的命令行工具也能實(shí)現(xiàn)和clap-rs的命令行提示一樣的效果呢?

三 clap-rs的命令行YAML文件

clap-rs包含了一個(gè)命令行工具的YAML規(guī)范。我們都知道命令行工具交互比較簡(jiǎn)單,主要就兩個(gè)部分:參數(shù)和子命令。你看到類似 --conf xxx.yaml 這些帶參數(shù)名的都屬于參數(shù),也可以省略參數(shù)名,如 convert a.jpg a.png 其中的a.jpg和a.png也都是參數(shù)。子命令就比較容易理解了,我們每天使用的git就是大量使用子命令的,如 git add xxx.jpg 這些。當(dāng)子命令還可以繼續(xù)套用子命令,子命令同時(shí)也擁有自己的參數(shù)。

基于命令行這樣的特性,我們完全可以將命令行工具的使用規(guī)范通過(guò)YAML描述出來(lái),現(xiàn)在一切皆可YAML。

這里我給出一個(gè)阿里云命令行工具的YAML定義,當(dāng)然只是demo。如下:

name: aliyun2 version: "0.1.0" about: "cli for Alibaba Cloud" args:- version:short: vlong: versiontakes_value: falseabout: Display version subcommands:- oss:about: 對(duì)象存儲(chǔ)subcommands:- cat:about: cat文本文件args:- file:takes_value: truerequired: trueabout: 文件名稱- ls:about: list文件- ecs:about: 云服務(wù)器subcommands:- SendFile:about: send file- AddTags:about: add tags

可以看出,我首先定義了兩個(gè)子命令:oss和ecs,然后oss子命令下我又定義了兩個(gè)子命令:cat和ls。對(duì)于oss的cat子命令,我又添加了file這個(gè)參數(shù),這樣我就可以使用cat來(lái)查看oss上文本文件的內(nèi)容。

有了這個(gè)命令行工具YAML規(guī)范定義后,我就可以調(diào)用clap-rs提供的命令行工具接口,生成對(duì)應(yīng)的shell的提示腳本。效果如下:

這個(gè)命令行提示的效果是不是比原先的要好多了?提示有了描述,選擇子命令和參數(shù)的時(shí)候就簡(jiǎn)單多了。

四 為所有命令行工具寫YAML

講到這里,相信大家都明白了。無(wú)論這個(gè)工具是Java,Python,Node.js還是Rust編寫的,首先定義好該工具的YAML規(guī)范,接下來(lái)開(kāi)發(fā)人員根據(jù)該規(guī)范去編寫代碼,他可以選擇他喜歡的語(yǔ)言,他喜歡的命令行解析器,然后實(shí)現(xiàn)對(duì)應(yīng)的功能即可。沒(méi)有代碼提升,編寫YAML文件不出錯(cuò)是非常難的,所以我做了一個(gè)JSON Schema[2]文件,在編寫YAML文件時(shí)可以進(jìn)行代碼提示,做到編寫命令行YAML規(guī)范文件更加簡(jiǎn)單。JSON Schema的使用方法如下:

接下來(lái)我們會(huì)基于該YAML文件,為各種shell生成對(duì)應(yīng)的命令行提示腳本,如bash,zsh,fish和powershell,這樣分開(kāi)后,開(kāi)發(fā)人員也不需要去處理那些他不清楚的命令行提示,或者找該編程語(yǔ)言對(duì)應(yīng)的SDK來(lái)做命令行代碼提示。如果沒(méi)有怎么辦?即便有了,生成的提示非常簡(jiǎn)單怎么辦?畢竟命令行工具提示非常重要。

相信Node.js的開(kāi)發(fā)者也不希望還要學(xué)習(xí)一下Rust和clap-rs,這樣就太不高效了。因此我又編寫了一個(gè)工具cli-completion[3], 其主要目的根據(jù)上面說(shuō)的YAML文件幫你自動(dòng)生成各種shell的命令行提示腳本。來(lái)看一下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

通過(guò)這種方式,cli-completion可以為任何命令提供命令行提示。也就是說(shuō),以后,你只要編寫命令行邏輯,關(guān)于命令行提示的問(wèn)題,全部交給cli-completion幫你生成即可。當(dāng)然考慮到用戶體驗(yàn),你可能需要在命令行工具中,將cli-completion生成的腳本,通過(guò)某一子命令,快速同步到客戶端環(huán)境。

命令行的開(kāi)發(fā)流程:YAML規(guī)范編寫,命令行提示自動(dòng)生成,開(kāi)發(fā)人員下班前完成功能實(shí)現(xiàn)。

有同學(xué)可能會(huì)問(wèn),我能否基于YAML文件,并結(jié)合某一命令行解析框架,自動(dòng)完成整個(gè)應(yīng)用的骨架生成,這完全可以,開(kāi)發(fā)人員只要實(shí)現(xiàn)一些函數(shù)即可,開(kāi)發(fā)會(huì)更簡(jiǎn)單。我個(gè)人認(rèn)為使用PicoCli這些框架自動(dòng)生成代碼,是完全沒(méi)有問(wèn)題的。

五 將cli-completion FaaS化

這個(gè)功能大家一年都未必用上兩次,費(fèi)時(shí)安裝也挺麻煩的。現(xiàn)在不是到處都是FaaS,我們也可以嘗試一下。首先cli-completion是用Rust編寫的,所以可以用傳統(tǒng)的方式編寫Rust Cloud Lambda,然后部署到云服務(wù)上,另外也可以寫一個(gè)Rust Web應(yīng)用,如用actix-web,也非常簡(jiǎn)單。

這些都不夠時(shí)髦,我們打算將cli-completion的代碼WebAssembly化,然后以FaaS方式部署,這里我選擇CloudFlare作為FaaS的運(yùn)行平臺(tái)。讓我們來(lái)看一下Demo。

創(chuàng)建一個(gè)cli.yaml文件,如下:

name: cli1 version: "0.1.0" about: "CLI completion for bash, zsh, fish and powershell." args:- help:short: hlong: helptakes_value: falseabout: Display this help

然后調(diào)用cli-completion的FaaS服務(wù),就可以得到對(duì)應(yīng)的命令行提示腳本代碼。命令如下:

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

對(duì)比傳統(tǒng)的cloud lambda或者cloud function,這種方式FaaS響應(yīng)速度最快,這種服務(wù)調(diào)用次數(shù)非常少,基本就是每次請(qǐng)求都是冷啟動(dòng),而WebAssembly這方面就非常有優(yōu)勢(shì)。

當(dāng)然還有一個(gè)最大的原因:就是WebAssembly方式的FaaS,它最便宜。

題外話探討一下cloudflare的WebAssmebly的實(shí)現(xiàn),純技術(shù)討論,代碼如下:

async function handleRequest(request) {const { greet } = wasm_bindgenawait wasm_bindgen(wasm)const greeting = greet()return new Response(greeting, {status: 200}) }

上述代碼中,wasm是一個(gè)WebAssembly.Module對(duì)象,它是從外部注入的,而不是開(kāi)發(fā)者寫的,是FaaS生成的。接下來(lái)就是從wasm_bindgen這個(gè)函數(shù)中獲取wasm的導(dǎo)出函數(shù),然后調(diào)用 wasm_bindgen(wasm) 將greet函數(shù)和wasm module中的export函數(shù)進(jìn)行關(guān)聯(lián),然后調(diào)用greet就會(huì)轉(zhuǎn)到wasm module的調(diào)用。如果是這樣的話,WebAssembly.Module其實(shí)是可以外部管理的,當(dāng)有請(qǐng)求時(shí),再和JavaScript的函數(shù)進(jìn)行關(guān)聯(lián),這樣就可以保證WebAssembly的快速響應(yīng)。

六 總結(jié)

以后大家在寫命令行工具時(shí),不用再擔(dān)心代碼提示的問(wèn)題了。在動(dòng)手開(kāi)發(fā)工具前,寫一下YAML文件,整理和厘清一下你的思路,有哪些子命令,有哪些參數(shù)等,然后再基于該YAML文件進(jìn)行開(kāi)發(fā),使用什么語(yǔ)言都沒(méi)有關(guān)系,最后配合cli-completion完成命令行提示,你的命令行工具算是相當(dāng)專業(yè)的了,至少?gòu)拿孀由峡雌饋?lái)是的 :)

最后列出一些命令行應(yīng)用涉及的至關(guān)重要的命令行解析器,方便大家后續(xù)參考:

  • 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

整理的不全,歡迎大家補(bǔ)充 :)

相關(guān)鏈接

[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

原文鏈接:https://developer.aliyun.com/article/779826?

版權(quán)聲明:本文內(nèi)容由阿里云實(shí)名注冊(cè)用戶自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,阿里云開(kāi)發(fā)者社區(qū)不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。具體規(guī)則請(qǐng)查看《阿里云開(kāi)發(fā)者社區(qū)用戶服務(wù)協(xié)議》和《阿里云開(kāi)發(fā)者社區(qū)知識(shí)產(chǎn)權(quán)保護(hù)指引》。如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,填寫侵權(quán)投訴表單進(jìn)行舉報(bào),一經(jīng)查實(shí),本社區(qū)將立刻刪除涉嫌侵權(quán)內(nèi)容。

總結(jié)

以上是生活随笔為你收集整理的命令行工具开发:如何快速实现命令行提示?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。