创建一个进程 (Bun.spawn())
提供一个字符串数组作为命令。Bun.spawn() 返回一个 Bun.Subprocess 对象。
Bun.spawn 的第二个参数是一个用于配置子进程的参数对象。
输入流
默认情况下,子进程的输入流未定义;请使用stdin 参数进行配置。
使用
"pipe" 时,父进程可以向子进程的输入流增量写入数据。
ReadableStream 传递给 stdin 时,它会将数据直接通过管道传输到子进程的输入流:
输出流
从stdout 和 stderr 属性读取子进程的输出。默认情况下,stdout 是 ReadableStream 的一个实例;stderr 继承自父进程,因此 proc.stderr 为 undefined。传入 stderr: "pipe",也可以为它获取一个 ReadableStream。
stdout/stderr 传入以下值之一来配置输出流:
退出处理
使用onExit 回调监听进程退出或被杀死。
index.ts
exited 属性是一个 Promise,在进程退出时解析。
index.ts
index.ts
bun 进程不会终止,直到所有子进程都已退出。使用 proc.unref() 将子进程与父进程分离。
index.ts
资源使用
进程退出后,resourceUsage() 会报告其资源使用情况:
index.ts
使用 cgroups 限制资源(Linux)
在 Linux 上,传入cgroup 可在控制组内启动子进程。子进程会在开始执行前加入 cgroup,因此在 cgroup 上配置的限制(内存、pids、CPU)从第一条指令起就会生效。这些限制也适用于子进程随后启动的每个进程。超过内存限制时,内核会在 cgroup 内部对进程执行 OOM 终止,而不是从父进程回收内存。
cgroup 是 /sys/fs/cgroup 下的一个目录;使用普通文件操作创建并配置它,然后传入其路径(或已打开的目录文件描述符):
index.ts
spawn;限制会应用于它们的总用量。Bun 同时支持 cgroup v1 和 v2 层级结构。创建 cgroup 通常需要 root 权限或一个已委派的子树。在其他平台上,Bun 会忽略此选项;在 Linux 上,如果子进程无法加入 cgroup,spawn 就会失败。
使用 AbortSignal
你可以使用AbortSignal 中止子进程:
index.ts
使用 timeout 和 killSignal
将timeout 设置为在经过指定的毫秒数后终止子进程:
index.ts
SIGTERM 终止超时的进程。使用 killSignal 选项指定其他信号:
index.ts
killSignal 选项也控制当 AbortSignal 中止时 Bun 发送的信号。
使用 maxBuffer
对于Bun.spawnSync,maxBuffer 限制进程在 Bun 将其终止前可以输出的字节数:
index.ts
maxBuffer,不会超过进程在终止生效前设法写入的任何额外内容。这与 Node.js 的行为一致。
进程间通信(IPC)
Bun 支持两个bun 进程之间的直接进程间通信通道。要接收由 Bun 子进程发送的消息,请指定一个 ipc 处理器。
parent.ts
Subprocess 实例上的 .send() 方法向子进程发送消息。ipc 处理器还会将发送消息的子进程作为第二个参数接收。
parent.ts
process.send() 向父进程发送消息,并通过 process.on("message") 接收消息。Node.js 在 child_process.fork() 中使用相同的 API。
child.ts
child.ts
serialization 选项控制两个进程间通信的序列化格式:
advanced:(默认)Bun 使用 JSCserializeAPI 序列化消息,该 API 支持克隆structuredClone支持的所有内容。此格式不支持转移对象的所有权。json:Bun 使用JSON.stringify和JSON.parse序列化消息,相比advanced,它支持的对象类型较少。
Bun 与 Node.js 之间的 IPC
要在bun 和 Node.js 进程间使用 IPC,请在 Bun.spawn 中设置 serialization: "json"。这是因为 Node.js 和 Bun 使用不同的 JS 引擎及不同的对象序列化格式。
bun-node-ipc.js
终端(PTY)支持
对于交互式终端应用,使用terminal 选项启动附加伪终端(PTY)的子进程。子进程会看到一个真实终端,从而支持彩色输出、光标移动和交互式提示。
terminal 选项时:
- 子进程中
process.stdout.isTTY为true stdin、stdout和stderr都绑定到终端proc.stdin、proc.stdout和proc.stderr返回null—— 使用终端对象代替- 可通过
proc.terminal访问终端
终端选项
终端方法
proc.terminal 返回的 Terminal 对象具有以下方法:
可复用终端
要通过同一个终端会话按顺序运行多个命令,可以独立创建终端,并在多个子进程之间复用:Terminal 对象时:
- 可以在多个 spawn 之间复用终端
- 可以自行控制何时关闭终端
exit回调会在调用terminal.close()时触发,而不是在每个子进程退出时触发- 使用
proc.exited检测各个子进程的退出状态
平台差异
Bun.Terminal 在 Linux 和 macOS 上使用 openpty(),在 Windows 上使用 ConPTY(CreatePseudoConsole)。所有平台上的核心行为都相同:子进程会看到一个 TTY,write() 会将数据写入子进程的 stdin,子进程输出会传递给 data 回调,resize() 会更新子进程看到的终端视图。部分细节有所不同:
- Windows 上没有 termios。
inputFlags、outputFlags、localFlags和controlFlags始终读取为0,设置这些值也不会产生效果。setRawMode()会记录该标志,但不会影响子进程;子进程会自行控制其控制台模式。 - Windows 上没有子进程时不会回显。 在 POSIX 上,即使没有附加进程,内核行规程也会将
write()输入回显到data回调。ConPTY 没有行规程;它会缓冲输入,等待下一个读取方。如果需要回显,请启动一个会回显输入的进程。 - ConPTY 会重新编码输出。 ConPTY 会将子进程的输出渲染到虚拟屏幕,并发出描述渲染结果的 VT 序列。因此,
data回调接收的转义序列在语义上等效,但字节内容不完全相同。ConPTY 会保留颜色和文本,但可能会重新排序或合并光标定位和重置序列。在任何子进程输出之前,ConPTY 还会发出一段简短的 VT 初始化序列(\x1b[?9001h\x1b[?1004h…)。 - Windows 上的输入
\r不会转换为\n。 POSIX 的ICRNL会在输入时将回车映射为换行;ConPTY 则会原样传递\r。 - 在 ConPTY 下,子进程中的
process.on('SIGWINCH')不会触发,除非子进程以原生模式读取 stdin。调用resize()后,process.stdout.columns/rows会更新。缺少此信号是 libuv 的限制,影响所有基于 libuv 的子进程(包括 Node.js)。 - 在 Windows 11 24H2(内部版本 26100)之前,
terminal.close()可能无法及时终止仍在运行的子进程。延迟来自ClosePseudoConsole:在这些版本中,它会阻塞,直到 conhost 将输出刷新到管道中。如果需要在子进程仍运行时拆除终端,请先杀死附加的进程。 - Windows 10 或 Windows Server 2019 上的鼠标跟踪不起作用。 这些版本中内置的 ConPTY(conhost 内部版本 17763 至 19045)早于 microsoft/terminal#4856,会丢弃子进程写入的鼠标跟踪启用序列(
\x1b[?1000h、\x1b[?1002h、\x1b[?1006h)。这些序列永远不会到达data回调,因此外部终端不会报告鼠标事件,子进程也不会收到鼠标事件。Windows 11 和 Server 2022 会转发这些序列,但只有在子进程写入这些序列前启用了 VT 输入模式(例如使用process.stdin.setRawMode(true))时才会转发。
阻塞式 API (Bun.spawnSync())
Bun.spawnSync 是 Bun.spawn 的阻塞式等价 API。它支持相同的输入和参数,并返回一个 SyncSubprocess 对象,该对象在几个方面不同于 Subprocess。
- 返回的对象包含一个
success属性,用于指示进程是否以零退出码退出。 stdout和stderr属性是Buffer的实例,而不是ReadableStream。- 没有
stdin属性。使用Bun.spawn可向子进程的输入流增量写入数据。
Bun.spawn 适合 HTTP 服务器和应用,Bun.spawnSync 更适合构建命令行工具。
性能基准
⚡️
Bun.spawn 和 Bun.spawnSync 使用 posix_spawn(3)。spawnSync 比 Node.js 的 child_process 模块快 60%。
terminal
terminal
参考
以下是 Spawn API 和类型的参考。实际类型包含复杂的泛型,用于根据传递给Bun.spawn 和 Bun.spawnSync 的选项,对 Subprocess 流进行强类型约束。完整详情请参阅 bun.d.ts。
查看可展开的 TypeScript 定义