能用Js實(shí)現(xiàn)的最終用Js實(shí)現(xiàn),Shell腳本也不例外
大家好,我是秋風(fēng)。
今天來(lái)討論一個(gè)牛逼的項(xiàng)目 ——zx ,1個(gè)月增長(zhǎng)15000 star, 成為了2021年度明星項(xiàng)目排行榜第一。
zx 到底是什么呢?
我們可以從官網(wǎng)的介紹看到,一個(gè)能更方便地寫(xiě)腳本的工具。(A tool for writing better scripts)
Bash is great, but when it comes to writing scripts, people usually choose a more convenient programming language. JavaScript is a perfect choice, but standard Node.js library requires additional hassle before using. The zx package provides useful wrappers around child_process, escapes arguments and gives sensible defaults.
翻譯:
Bash 用來(lái)寫(xiě)腳本非常棒,但是大家通常還是會(huì)去選擇一種更方便方式去編寫(xiě)腳本,例如使用像 JavaScript 這種編程語(yǔ)言。但是 Node.js 在使用之前需要很多額外的操作,比如裝包、引庫(kù)等。但是zx 提供更多便捷的功能并且還對(duì) child_process 進(jìn)行了簡(jiǎn)化封裝,從而能夠直接調(diào)用一些命令。
通過(guò)閱讀摘要和描述,我們可以知道雖然 Bash 很棒,但是沒(méi)有 Node.js 簡(jiǎn)單。雖然 Node.js 編寫(xiě)起來(lái)簡(jiǎn)單,但是在使用前還是有一些麻煩的操作。而zx 沒(méi)有以上兩種方式的缺點(diǎn),能夠化繁為簡(jiǎn),提供簡(jiǎn)單又方便操作。
在繼續(xù)深入了解 zx 前,我們先來(lái)屢清楚目前提到的一些概念,了解這些概念有助于我們更好地去寫(xiě)腳本。
Shell、Shell腳本、Bash、zx、Node
首先來(lái)說(shuō)說(shuō)什么是Shell,Shell的中文意思是貝殼,是指與操作內(nèi)核連接的外殼。
狹義的Shell指的是命令行方面的軟件,大多指Bash(Bash全稱為 Bourne Again SHell ,是linux標(biāo)準(zhǔn)的默認(rèn)Shell,它基于Bourne Shell,吸收了C Shell和Korn Shell );廣義的Shell則包括圖形界面。
因此 Shell 是一個(gè)大概念,包含了 Bash 等這些命令行工具,而利用這些工具寫(xiě)的腳本叫做Shell 腳本;而 Node 屬于編程語(yǔ)言,可以編寫(xiě) js 文件來(lái)執(zhí)行一些命令, zx 是基于 Node 開(kāi)發(fā)的工具,因此也能通過(guò)編寫(xiě)腳本來(lái)執(zhí)行命令。
他們之間的關(guān)系我用一張圖進(jìn)行了描述,標(biāo)題的概念用紅色字樣進(jìn)行了加重。
腳本可以做那些事情?
最為簡(jiǎn)單的就是重復(fù)的事情、處理數(shù)據(jù)格式,數(shù)據(jù)導(dǎo)入導(dǎo)出以及各種簡(jiǎn)單常用小工具的制作,環(huán)境配置等等。
舉一些具體的例子就是:
下載視頻
https://www.jianshu.com/p/0a013fa5a250
下載音樂(lè)
https://binaryify.github.io/NeteaseCloudMusicApi/#/
統(tǒng)計(jì)字?jǐn)?shù)
https://geek-docs.com/shell/shell-examples/the-shell-counts-the-number-of-lines-words-and-characters-in-the-file.html
自動(dòng)簽到
https://github.com/RWoxiN/Qiandao
...
功能太多了列舉不過(guò)來(lái),反正你會(huì)的操作能幫你簡(jiǎn)化,你不會(huì)的操作能幫你實(shí)現(xiàn)。
哪些人可以使用?
腳本不僅僅可以幫助開(kāi)發(fā)人員還能幫助非開(kāi)發(fā)人員。
例如很多人都喜歡在個(gè)人博客上面寫(xiě)文章,這時(shí)就可以用WordPress 快速搭建一個(gè)博客,然后我們就用腳本一鍵來(lái)安裝WordPress,下面以 Shell 腳本為例:
https://gist.github.com/dessibelle/2666478
zx、Node、Shell(Bash) 功能評(píng)測(cè)
上面聊了腳本的一些概念以及腳本能幫助我們做什么。那么既然腳本這么強(qiáng)大,且腳本種類也非常多,為什么 zx 一經(jīng)推出就這么收歡迎呢?
我們就以實(shí)際的功能為例來(lái)體驗(yàn)一下,分別使用了zx、Node、Shell(Bash,以下都稱作Bash )三種腳本寫(xiě)一個(gè)批量壓縮音視頻的腳本。
實(shí)現(xiàn)一個(gè)音頻功能主要分成四個(gè)步驟
1.遍歷當(dāng)前目錄
2.判斷當(dāng)前文件類型
3.執(zhí)行壓縮音頻視腳本
首先我們先來(lái)看遍歷當(dāng)前目錄三種腳本的寫(xiě)法:
Bash
- #!bin/bash
- for file in `(ls)`;
- do
- ...
- done
Node
- import fs from 'fs';
- const dirs = fs.readdirSync('./'));
- for (let i in dirs) {
- ...
- }
zx
- const dirs = (await $`ls`).stdout.split('\n')
- for (let i in dirs) {
- ...
- }
可以看到 Bash 和 zx 差不多,但是 zx 比Node 省去了引包的代碼。
優(yōu)勢(shì):zx = Bash > Node
其次我們?cè)賮?lái)看判斷當(dāng)前文件類型三種腳本的寫(xiě)法:
Bash
- if test -f $file
- then
- filename=$(basename $file);
- if [ "${file##*.}"x = "mp4"x ];then
- fi
- if [ "${file##*.}"x = "mp3"x ]; then
- fi
- fi
Node、zx
- if (dirs[i] && !fs.statSync(source).isDirectory()) {
- if (source.endsWith(".mp4")) {
- }
- if (source.endsWith(".mp3")) {
- }
- }
用Shell 來(lái)寫(xiě)整體上代碼都非常的精煉,但是對(duì)于不經(jīng)常使用的人來(lái)說(shuō),常常會(huì)遇到一些問(wèn)題,例如 if 語(yǔ)句格式非常嚴(yán)格、判斷比較的方式比較特殊、字符串操作都比較麻煩。
優(yōu)勢(shì) Node = zx > Bash
最后再來(lái)執(zhí)行壓縮音頻視腳本:
Bash
- ...
- ffmpeg -i $file -r 30 -c copy -c:v libx264 -vf scale=720:-2 "${filename%%.*}-30-720".mp4;
- ...
Node
- const { spawn } = require('child_process');
- function run(command) {
- return new Promise((rev, rej) => {
- console.log(command);
- const cmd = spawn(command.slice(0, 1)[0], command.slice(1));
- cmd.stdout.on('data', (data) => {
- console.log(`stdout: ${data}`);
- });
- cmd.stderr.on('data', (data) => {
- console.error(`stderr: ${data}`);
- });
- cmd.on('close', (code) => {
- console.log(`child process exited with code ${code}`);
- rev();
- });
- })
- }
- ...
- await run(["ffmpeg", "-i", source ,"-r","30","-c", "copy","-c:v", "libx264", "-vf", "scale=720:-2", `${dirs[i].replace('.mp4', '')}-30-720.mp4`]);
- ...
zx
- $`ffmpeg -i ${file} -r 30 -c copy -c:v libx264 -vf scale=720:-2 ${file.replace(".mp4","")}-30-720.mp4;`;
用 zx 可以做到和 Shell 一樣的精簡(jiǎn),利用內(nèi)置的一些 Node 包使得整體的代碼量大大下降。Node需要寫(xiě)一些額外的代碼,例如執(zhí)行命令run等等。
優(yōu)勢(shì) Bash = zx > Node
上手程度 | 代碼復(fù)雜度 | |
---|---|---|
Shell | 難 | 簡(jiǎn)潔 |
Node | 簡(jiǎn)單 | 繁瑣 |
zx | 簡(jiǎn)單 | 簡(jiǎn)潔 |
zx 上手體驗(yàn)非常好,可以說(shuō)用四個(gè)字來(lái)概括, “簡(jiǎn)潔易用”,至此你是否對(duì) zx 心動(dòng)了呢?