使用 zx 编写在 Node 中编写 Bash 脚本

news/2024/12/3 5:02:28/

本文已整理到 Github,地址 👉 blog

如果我的内容帮助到了您,欢迎点个 Star 🎉🎉🎉 鼓励鼓励 :) ~~


Bash 是一种命令语言,通常作为命令行解释程序出现,用户可以在其中从他们的终端软件执行命令。例如,我们可以使用 Ubuntu 的终端来运行 Bash 命令。我们还可以通过 shell 脚本创建和运行 Bash 脚本文件。

我们经常在许多自动化场景中使用 shell 脚本,例如构建过程、CI/CD 或与计算机维护相关的活动。作为一种功能齐全的命令语言,Bash 支持管道、变量、函数、控制语句和基本算术运算。

然而,Bash 不是一种通用的开发人员友好型编程语言。它不支持 OOP、JSON 等结构、数组以外的通用数据结构,以及内置的字符串或数组操作方法。这意味着程序员通常需要从 Bash 中调用单独的 Python 或 Node 脚本来满足这些需求。

这就是 zx 项目的用武之地。zx 引入了一种使用 JavaScript 编写类似 Bash 的脚本的方法。

相比之下,JavaScript 几乎具有开发人员所需的所有内置功能。zx 允许我们通过为几个关键的 CLI 相关 Node.js 包提供包装 API(如:child_process),用 JavaScript 编写 shell 脚本。因此,可以使用 zx 编写开发人员友好的、类似 Bash 的 shell 脚本。

本文将介绍 zx 的一些用法,如何在项目中使用它。

zx 是如何工作的?

每个 zx shell 脚本文件都有 .mjs 扩展名。第三方 API 的所有内置函数和包装器都是预先导入的。因此,您不必在基于 JavaScript 的 shell 脚本中使用额外的 import 语句。

zx 接受来自标准输入、文件和 URL 的脚本。它将您的 zx 命令集导入为 ECMAScript 模块(MJS)来执行,命令执行过程使用 Node.js 的 child_process API。

安装

全局安装 zx:

$ npm i -g zx

版本要求:node >= 16.0.0

在终端运行 zx 以检查程序是否已成功安装:

$ zxUsage:zx [options] <script>Options:--quiet            : don't echo commands--shell=<path>     : custom shell binary--prefix=<command> : prefix all commands--experimental     : enable new api proposals--version, -v      : print current zx version

你也可以单独在项目引入。

顶层 await

为了在 Node.js 中使用顶级 await,在异步函数之外进行 await,我们需要在 ES 模块中编写代码,它支持顶级 await

我们可以通过在 package.json 中添加 "type": "module" 来表示项目中的所有模块都是 ES 模块,或者我们可以将单个脚本的文件扩展名设置为 .mjs

基本语法

首先,文件扩展使用 .mjs 以便可以在顶层使用 await,如果您还是喜欢原来的 .js,需要包装一个 async 函数。

其次,需要在文件的顶部加上 #!/usr/bin/env zx

以下是获取项目的当前 Git 分支示例:

// demo.mjs
#!/usr/bin/env zxconst branch = await $`git branch --show-current`
console.log(`当前分支:${branch}`)
  • #!/usr/bin/env zx 告诉操作系统的脚本执行器选择正确的解释器。
  • $ 是一个函数,它执行给定的命令,并在与 await 关键字一起使用时返回其输出。

最后,我们使用 console.log 来显示当前分支。

运行脚本,以获取项目的当前 Git 分支:

$ zx demo.mjs

它还将显示您执行的每个命令,因为 zx 在默认情况下打开了详细模式。

通过添加以下内容,即可消除额外的命令详细信息。

$.verbose = false

由于我们在第一行使用了 shebang(#!),我们也可以在不使用 zx 命令的情况下运行脚本。

$ chmod +x ./demo.mjs

颜色和格式

zx 暴露了 chalk API。因此,我们可以使用它进行着色和格式化,如下所示。

#!/usr/bin/env zx$.verbose = false
let branch = 1
chalk.level = 1
console.log(`当前分支:${chalk.red.bold(branch)}`)

查看 chalk 的官方文档以了解更多的着色和格式化方法。

用户输入和命令行参数

zx 提供提问功能,从命令行界面捕获用户输入。您还可以使用选项来启用传统的 Unix 选项卡完成功能。

它使用的是 Node 的 readline 包。

以下脚本将捕获文件名和模板。它使用用户输入的配置构建一个文件。

#!/usr/bin/env zx
$.verbose = false
let filename = await question('文件名是什么? ')
let template = await question('你最喜欢的模板是什么? ', {choices: ['function', 'class']
})
let content = ''if (template == 'function') {content = `function main() {console.log('Test')
}`
} else if (template == 'class') {content = `class Main {constructor() {console.log('Test')}
}`
} else {console.error(`无效模板: ${template}`)process.exit()
}fs.outputFileSync(filename, content)

已解析的命令行参数对象可作为全局 argv 常量使用。解析是使用 minimist 模块完成的。

下面的示例捕获了两个命令行参数值。

#!/usr/bin/env zx
$.verbose = false
const size = argv.size
const isFullScreen = argv.fullscreen
console.log(`size=${size}`)
console.log(`fullscreen=${isFullScreen}`)

运行上述脚本文件,以检查命令行参数的支持。

$ zx ./demo .mjs --size=1080 --fullscreen# size=1080
# fullscreen=true

网络请求

我们经常使用 curl 命令通过 Bash 脚本发出 HTTP 请求。zx 为 node-fetch 模块提供了一个包装器,它将特定模块的 API 公开为 fetch。优点是 zx 不会像 Bash 使用 curl 那样为每个网络请求生成多个进程 ,因为 node-fetch 包使用 Node 的标准 HTTP API 来发送网络请求。

以下使用 zx 发送 HTTP 请求:

#!/usr/bin/env zx$.verbose = false
let response = await fetch('https://jsonplaceholder.typicode.com/todos/1')
if (response.ok) console.log(await response.text())/*
{"userId": 1,"id": 1,"title": "delectus aut autem","completed": false
}
*/

构建命令管道

在 shell 脚本中,管道指的是多个顺序执行的命令。我们经常在 shell 脚本中使用众所周知的管道字符(|),将输出从一个进程传递到另一个进程。zx 提供了两种不同的方法来构建管道。

我们可以将 | 字符与类似于 Bash 脚本的命令集一起使用 ,或者我们也可以使用 zx 内置 API 中的 pipe() 方法。

使用 |

#!/usr/bin/env zx$.verbose = false
let greeting = await $`echo "hello World" | tr '[h]' [H]`
console.log(`${greeting}`)

使用 pipe()

#!/usr/bin/env zx$.verbose = false
let greeting = await $`echo "Hello world"`.pipe($`tr '[w]' [W]`)
console.log(`${greeting}`)

高级用法

除了基于 JavaScript 的 shell 脚本支持外,zx 还支持其他一些有用的功能。

默认情况下,zx 使用 Bash 解释器来运行命令。我们可以通过修改 $.shell 来更改默认 shell 配置变量。下面的脚本使用 sh shell 而不是 bash。

$.shell = '/usr/bin/sh'
$.prefix = 'set -e;'$`echo "Your shell is $0"` // Your shell is /usr/bin/sh

zx 命令行程序也可以从 URL 运行远程脚本。以提供文件名的方式提供 zx 脚本的链接。

以下是 zx 仓库提供的一个示例:

$ zx https://github.com/google/zx/blob/main/examples/interactive.mjs

其他:

  • 与 TypeScript 一起使用
  • GitHub Actions
  • etc

详细内容可以查看官方文档。


http://www.ppmy.cn/news/129953.html

相关文章

h2ouve下载 insyde_神舟tx6zx6gx9tx9蓝天模具解锁bios高级菜单

本帖最后由 xyingtao 于 2020-8-21 09:47 编辑 刷BIOS有风险!刷前请三思! 理论适用机型: 使用insyde bios 的tx系列 zx系列 gx系列 具体请自己对应官网的bios固件 不保证其它机型适用 原教程帖地址:https://www.bilibili.com/read/cv5652930 神舟官方bios固件下载地址:http:/…

下拉框优化威zx78_下拉框选中从zx78

做推广的人都离不开搜索引擎&#xff0c;就像鱼离不开水&#xff0c;很多时候我们做SEO的朋友都在研究各大搜索引擎的机制&#xff0c;收录&#xff0c;排名规则或者是黑帽技术&#xff0c;不管如何&#xff0c;只是希望把自己的企业&#xff0c;产品&#xff0c;服务在搜索上得…

聊聊去年最火的前端库zx

根据github上的数据&#xff0c;去年最受欢迎的前端库为谷歌棋下的zx。今天我们就来聊一聊这个去年最火的前端库。 zx是什么 zx 是谷歌实现的一个能在 node 中写 bash 的库。就像这样&#xff1a; await $echo "hello world";使用$框起想要执行的命令&#xff0c;…

ZX297520V3T:Codec NAU88C22驱动调试

一、音频驱动框架 ALSA(Advanced Linux Sound Architecture)是目前linux的主流音频体系结构。ALSA不仅在内核设备驱动层提供了alsa-driver,同时在应用层为我们提供了alsa-lib,应用程序只要调用alsa-lib提供的API,即可以完成对底层音频硬件的控制。为了方便调试,ALSA也提…

byzx

《点击下载》[BT下载][白夜追凶][全32集打包][国语中字][MP4][1080P]

ZX7520 V3

1.脚本中需要打开或添加下载初始化&#xff08;下载tloader,tboot,partition文件)&#xff0c;下图为允许下载初始化执行&#xff0c;并在函数下拉框中选择如图所示的内容。 2.配置界面选择正确的出货版本 3.修改配置文件需要在ZX7520V3_Config.ini中配置内部和外部软件版本号相…

我眼中的ZX-2 FPGA开发板

下面是ZX-2开发板的板载资源&#xff1a; 1、四个轻触按键 2、蜂鸣器 3、Sdram是现代的HY57V281620A 4、138译码的数码管&#xff0c;译码芯片为74H138 5、VGA接口 6、PS/2键盘接口 7、USB转串口接口 8、30pins外接IO 9、AS接口用于烧写FPGA配置FLASH 10、 …

神舟zx8sp7s2装linux,战神ZX8-SP7S2游戏本搭GTX1070+桌面i7芯

大事件!超级丹出轨小野模被爆!奥运冠军的高大形像一落千丈,人设全塌。人要始终如一,有如神舟电脑专注做游戏本。神舟推出GTX1070独显游戏本——战神ZX8-SP7S2,搭载英伟达第六代全新Skylake平台i7-6700,融入十系最新最强显卡GTX1070,8GGDDR5显存性能强大,上市便激起游戏…