Shell 解释器是 Bun 内置的跨平台 shell 实现,可在 Windows、macOS 和 Linux 上提供一致的 shell 行为。它支持执行 shell 命令、脚本,并提供用于程序化 shell 操作的 JavaScript API。
有关 shell 脚本解析和词法分析的信息,请参阅 JavaScript 处理引擎文档。有关子进程执行的详细信息,请参阅 进程 API 和环境。
Shell 解释器由多个关键组件组成,协同工作以提供 shell 功能
架构组件图
来源:src/shell/interpreter.zig348-914 src/shell/shell.zig323-892 src/js/builtins/shell.ts1-150
Shell 解释器通过模板字面量和基于 Promise 的接口公开 JavaScript API
JavaScript API 结构
ShellPromise 类扩展了 Promise 并提供了配置方法
quiet() - 抑制 stdout/stderr 输出nothrow() - 非零退出代码时不抛出错误cwd(path) - 设置工作目录env(vars) - 设置环境变量来源:src/js/builtins/shell.ts106-150 test/js/bun/shell/bunshell.test.ts7-33
核心解释器采用状态机架构来处理非阻塞执行
解释器状态机
解释器避免阻塞,它将执行实现为状态机,而不是传统的树遍历。每个状态都可以让出执行权,并在异步操作完成后稍后恢复。
StateKind 中定义了关键状态类型
script - 根脚本执行stmt - 语句处理cmd - 单个命令执行pipeline - 管道命令处理async - 异步命令处理来源:src/shell/interpreter.zig92-104 src/shell/interpreter.zig346-914 src/shell/interpreter.zig175-179
命令流经多个处理阶段
命令处理流水线
shell 在 AST 中定义了各种命令结构
Cmd - 带有参数的简单命令Pipeline - 管道命令序列Binary - 逻辑运算符(&&、||)Assign - 变量赋值If - 条件执行Subshell - 子 shell 执行来源:src/shell/shell.zig708-714 src/shell/shell.zig637-648 test/js/bun/shell/bunshell.test.ts395-407
Shell 在命令执行过程中维护全面的状态
Shell 状态管理
ShellState 支持不同的执行上下文
normal - 标准 shell 执行cmd_subst - 命令替换subshell - 子 shell 执行pipeline - 管道命令处理环境变量在三个作用域中管理
来源:src/shell/interpreter.zig390-495 src/shell/interpreter.zig425-430 src/shell/interpreter.zig546-553
Shell 通过非阻塞操作实现了复杂的 IO 处理
IO 系统架构
IO 系统使用 CowFd(写时复制文件描述符)来安全地处理并发访问。当多个操作尝试写入同一个文件描述符时,它会自动复制该描述符以避免冲突。
重定向标志支持常见的 shell 模式
> - 重定向 stdout2> - 重定向 stderr&> - 同时重定向>> - 追加模式1>&2 - 将 stdout 复制到 stderr来源:src/shell/interpreter.zig114-173 src/shell/interpreter.zig181-312 src/shell/shell.zig727-793
shell 提供了许多内置命令,用于文件操作和系统交互
| 命令 | 目的 | 实现 |
|---|---|---|
echo | 将文本打印到 stdout | 带变量展开的文本输出 |
cd | 更改目录 | 更新 ShellState 工作目录 |
pwd | 打印工作目录 | 返回当前的 ShellState.cwd |
ls | 列出目录内容 | 带格式的文件系统遍历 |
rm | 删除文件/目录 | 带安全检查的递归删除 |
mv | 移动/重命名文件 | 带错误处理的文件系统操作 |
cp | 复制文件 | 带目录支持的文件复制 |
cat | 显示文件内容 | 将文件内容流式传输到 stdout |
touch | 创建/更新文件 | 文件创建和时间戳更新 |
mkdir | 创建目录 | 带 -p 支持的目录创建 |
which | 查找命令 | PATH 搜索可执行文件 |
dirname | 提取目录路径 | 路径操作实用程序 |
basename | 提取文件名 | 路径操作实用程序 |
内置命令与 shell 的状态管理和 IO 系统直接集成,比外部命令提供更好的性能和一致性。
来源:test/js/bun/shell/bunshell.test.ts56-86 test/js/bun/shell/commands/rm.test.ts27-52 test/js/bun/shell/commands/mv.test.ts10-52
Shell 解释器通过以下方式提供跨平台的统一行为
解释器会透明地处理平台差异,使 Shell 脚本能够根据底层操作系统一致地运行。
来源: src/shell/interpreter.zig34-38 src/shell/shell.zig34-40 test/js/bun/shell/bunshell.test.ts15-28