菜单

Shell 解释器

相关源文件

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

JavaScript API

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 - 管道命令处理

环境变量在三个作用域中管理

  • 用于展开的 Shell 环境
  • 用于单个命令的本地环境
  • 用于所有子进程的导出环境

来源:src/shell/interpreter.zig390-495 src/shell/interpreter.zig425-430 src/shell/interpreter.zig546-553

IO 和重定向

Shell 通过非阻塞操作实现了复杂的 IO 处理

IO 系统架构

IO 系统使用 CowFd(写时复制文件描述符)来安全地处理并发访问。当多个操作尝试写入同一个文件描述符时,它会自动复制该描述符以避免冲突。

重定向标志支持常见的 shell 模式

  • > - 重定向 stdout
  • 2> - 重定向 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 解释器通过以下方式提供跨平台的统一行为

  • 路径处理 - Windows 和 POSIX 路径之间的自动转换
  • 文件描述符 - 跨平台的统一 FD 抽象
  • 进程执行 - 特定于平台的子进程处理
  • 环境变量 - 一致的变量扩展和继承
  • 内置命令 - 常见实用程序的跨平台实现

解释器会透明地处理平台差异,使 Shell 脚本能够根据底层操作系统一致地运行。

来源: src/shell/interpreter.zig34-38 src/shell/shell.zig34-40 test/js/bun/shell/bunshell.test.ts15-28