使用Zx.js框架更方便的操作shell


 zx.js是google最近頻繁更新的一個github代碼庫,它的作用是將JavaScript和傳統的shell命令相結合,使得開發者擁有更強大的操控能力。

先來簡單介紹一下shell,shell 是一個用 C 語言編寫的程序,bash是大多數Linux系統以及Mac OS X默認的shell,shell是用戶和Linux之間的橋梁,它是一種命令式語言,當我們執行shell腳本的時候,可以打開終端,輸入命令后回車執行,例如我們平時常用的cd mydir就是一條shell基礎命令;同時它又是一種程序設計語言,可以以編程的方式來進行書寫,它支持變量,數組,以及運算符操作等等,傳統的shell腳本通常以.sh執行腳本文件結尾。

shell命令大家在日常開發中都會經常使用,比如進入目錄,創建、移動、刪除文件,查看文件夾內容、操作git命令等等,但是shell文件並不一定每個開發人員都寫過,正是由於shell的語法特殊性使得它有一定的學習成本,苛刻的縮進規則和啰嗦的語法規則往往讓編寫shell頭痛不已;

我們看下面這段while循環代碼:

1 int=1
2 while(( $int<=5 ))
3 do
4     echo $int
5     let "int++"
6 done

再看一段比較運算符的代碼:

a=10
b=20

if [ $a -eq $b ]
then
   echo "$a -eq $b : a 等於 b"
else
   echo "$a -eq $b: a 不等於 b"
fi

 

可能到這里一些前端開發工程師還不太理解為什么要用shell,前端開發明明都會寫node,我們也經常使用node的基礎模塊來跟操作系統打交道啊,像我們平時用的fs模塊,os模塊都挺好用的。沒錯,雖然node為我們封裝了一些控制操作系統的能力,但是它只是shell能力的冰山一角,還不能完全代替shell,這就是node中child_process模塊存在的原因。

下圖展示了使用child_process在JS文件中調用shell的方式, 相當於執行了shell的ls -lh /usr語句,但是開發者需要在輸入shell命令的時候先對命令和參數進行一定格式轉換,這種偵聽事件回調的調用方式使用起來非常割裂且繁瑣

const { spawn } = require('child_process');
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.error(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

 

zx.js的作者希望以更加友好的方式讓前端工程師既能用JS方便的執行shell腳本。

需要說明的是,為了能夠在zx語句中讓await語法在頂層使用,需要創建.mjs為擴展名的文件,它代表zx的可執行腳本文件,如果依然堅持用js文件,需要將腳本包裝在void async function () {...}()中,推薦使用mjs文件創建,更加簡單清晰;;

zx.js提供了一些全局函數,如$,cd,fetch等,且無需導入;

 

如$`command`的語法執行shell,$操作符像jQuery的$一樣方便,隨時隨地調用,非常方便且自然,在js文件中。

上面的語句可以在js中直接寫作:

$`ls -lh /usr`

 

一個小小的$,即把 child_process封裝在內,和JS之間的相互調用渾然天成

const processOutput = $`ls -lh /usr`
console.log(processOutput.stdout) // 輸出內容

 

processOutput對象定義如下,可以通過此對象獲取到輸出的錯誤和文本內容等;

class ProcessOutput {
  readonly stdout: string
  readonly stderr: string
  readonly exitCode: number
  readonly signal: 'SIGTERM' | 'SIGKILL' | ...
  toString(): string
}

 

zx.js也內置了一些函數,使開發者能夠更加方便的調用shell命令

cd:

cd('/tmp')
await $`pwd` // outputs /tmp

 

fetch:

let resp = await fetch('https://wttr.in')
if (resp.ok) {
  console.log(await resp.text())
}

 

sleep:

await sleep(1000)

 

等等

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM