shell腳本是一個(gè)命令語(yǔ)言,面向的是操作系統(tǒng)執(zhí)行。如果寫(xiě)過(guò)shell腳本的話,應(yīng)該體會(huì)過(guò)編寫(xiě)過(guò)程的痛苦。因?yàn)閟hell并不是一個(gè)編程語(yǔ)言,并不支持常見(jiàn)的數(shù)組,JSON等數(shù)據(jù)結(jié)構(gòu),也不支持面向?qū)ο缶幊痰拈_(kāi)發(fā)方法,因此對(duì)開(kāi)發(fā)人員很不友好。
目前針對(duì)這種情況,大家一般會(huì)用shell調(diào)用node執(zhí)行JS腳本,真正的處理邏輯放在JS腳本中處理。現(xiàn)在谷歌推出了 ZX NPM包,它能夠用JS編寫(xiě)shell腳本。
那如何使用呢?
1.全局安裝zx
npm install -g zx
安裝完后,在終端中輸入 zx 命令檢查安裝是否成功。
2.創(chuàng)建一個(gè)簡(jiǎn)單的腳本
新建zx腳本文件:test.mjs
#!/usr/bin/env zx
const branch = await $`git branch --show-current`
console.log(`Current branch: ${branch}`)
第一行是指定腳本的執(zhí)行器。
$ 是內(nèi)置的函數(shù),能夠執(zhí)行命令并配合 await 返回執(zhí)行結(jié)果。其他的寫(xiě)法都和JS毫無(wú)差別。
3.執(zhí)行腳本
zx ./test.mjs
或者:
chmod +x ./test.mjs
./test.mjs
控制臺(tái)就會(huì)輸出當(dāng)前的分支。
上面只是小試牛刀,zx 的強(qiáng)大遠(yuǎn)不止如此。由于 zx 在內(nèi)部實(shí)現(xiàn)了 Bash 的解釋器,所以可以執(zhí)行全部的shell命令。另外 zx 還內(nèi)置很多nodejs模塊,比如 fs, os,fetch等。所以可以直接在腳本中使用這些模塊。
另外作為T(mén)S編寫(xiě)的庫(kù),全部的JS語(yǔ)法都能夠支持。包括但不限于 數(shù)組,Promise,class等。
下面再舉一個(gè)例子:
let resp = await fetch('http://wttr.in')
if (resp.ok) {
console.log(await resp.text())
}
let hosts = [...]
await Promise.all(hosts.map(host =>
$`rsync -azP ./src ${host}:/var/www`
))
try {
await $`exit 1`
} catch (p) {
console.log(`Exit code: ${p.exitCode}`)
console.log(`Error: ${p.stderr}`)
}
總結(jié)一下,zx 的最大優(yōu)點(diǎn)是結(jié)合了Bash和JAVAScript,解決了shell腳本復(fù)雜邏輯編程的問(wèn)題。同時(shí)也讓對(duì)shell不熟悉的開(kāi)發(fā)者也能用JS完成shell腳本的開(kāi)發(fā),而且更加靈活高效。
如果你還有更多問(wèn)題,可以參考NPM倉(cāng)庫(kù) zx 包的介紹,或者訪問(wèn)其github地址。