zx 是一个更方便、更友好帮助开发者写脚本的工具。有 Google “爸爸”的光环加持,该工具短短几天在 GitHub 上就破万 Star 了。
Bash 很好,但是在编写脚本的时候,人们通常会选择一种更方便的编程语言,JavaScript 就是一个很完美的选择。但是标准的 Node.js 库在使用之前需要许多额外的操作,比如安装、引入库等,zx 提供一个包装器 child_process,用于转义参数并提供合并的默认值。
#!/usr/bin/env?zx??await?$`cat?package.json?|?grep?name`??let?branch?=?await?$`git?branch?--show-current`??await?$`dep?deploy?--branch=${branch}`??await?Promise.all([??$`sleep?1;?echo?1`,??$`sleep?2;?echo?2`,??$`sleep?3;?echo?3`,??])??let?name?=?'foo?bar'??await?$`mkdir?/tmp/${name}`?
项目地址是:
https://github.com/google/zx
安装
npm?i?-g?zx?
简单使用。将编写的脚本放在 .mjs 后缀的文件中,或者使用 .js 后缀,但是需要 void async function () {...}() 对脚本进行包装。
脚本需要包含以下文件头:
#!/usr/bin/env?zx?
运行脚本(需要先添加执行权限):
chmod?+x?./script.mjs??./script.mjs??//?或者使用这个命令??zx?./script.mjs?
使用child_process包中提供的exec函数可以把字符串当做命令执行,并返回Promise<ProcessOutput>对象。
let?count?=?parseInt(await?$`ls?-1?|?wc?-l`)??console.log(`Files?count:?${count}`)?
例如,并行上传文件:
let?hosts?=?[...]??await?Promise.all(hosts.map(host?=>??$`rsync?-azP?./src?${host}:/var/www`??))?
如果执行脚本返回非0状态码,将会抛出ProcessOutput对象:
try?{??await?$`exit?1`??}?catch?(p)?{??console.log(`Exit?code:?${p.exitCode}`)??console.log(`Error:?${p.stderr}`)??}?
抛出ProcessOutput对象结构如下:
class?ProcessOutput?{??readonly?exitCode:?number??readonly?stdout:?string??readonly?stderr:?string??toString():?string??}?
cd(),修改工作路径:
cd('/tmp')??await?$`pwd`?//?outputs?/tmp?
fetch(),对node-fetch包的包装:
let?resp?=?await?fetch('http://wttr.in')??if?(resp.ok)?{??console.log(await?resp.text())??}?
question(),对readline包的包装:
type?QuestionOptions?=?{?choices:?string[]?}??function?question(query:?string,?options?:?QuestionOptions):?Promise<string>?
用法:
let?username?=?await?question('What?is?your?username??')??let?token?=?await?question('Choose?env?variable:?',?{??choices:?Object.keys(process.env)??})?
chalk包,不需要导入就可以直接用
console.log(chalk.blue('Hello?world!'))?
fs包,需要导入就可以直接用
let?content?=?await?fs.readFile('./package.json')?
Promisified默认被引入了,相当于写了以下代码:
import?{promises?as?fs}?from?'fs'?
os包,需要导入就可以直接用
await?$`cd?${os.homedir()}?&&?mkdir?example`?
zx可以从其他脚本导入:
#!/usr/bin/env?node??import?{$}?from?'zx'??await?$`date`?
传递环境变量:
process.env.FOO?=?'bar'??await?$`echo?$FOO`?
执行远程脚本:
zx?https://medv.io/example-script.mjs?
领取专属 10元无门槛券
私享最新 技术干货