Bun 进程与子进程 #
概述 #
Bun 提供了强大的进程管理能力,包括 process 全局对象、Bun.spawn() 子进程创建和 Shell 命令执行功能。
process 全局对象 #
进程信息 #
typescript
// 进程 ID
console.log(process.pid); // 当前进程 ID
console.log(process.ppid); // 父进程 ID
// 进程标题
console.log(process.title);
// 版本信息
console.log(process.version); // Node.js 版本字符串
console.log(process.versions); // 版本详情
// 平台信息
console.log(process.platform); // "darwin", "linux", "win32"
console.log(process.arch); // "x64", "arm64"
// 运行时信息
console.log(process.uptime()); // 进程运行时间(秒)
环境变量 #
typescript
// 读取环境变量
console.log(process.env.NODE_ENV);
console.log(process.env.PATH);
console.log(process.env.HOME);
// 设置环境变量
process.env.MY_VAR = "value";
// 删除环境变量
delete process.env.MY_VAR;
// 遍历所有环境变量
for (const [key, value] of Object.entries(process.env)) {
console.log(`${key}=${value}`);
}
命令行参数 #
typescript
// 完整参数列表
console.log(process.argv);
// ["/path/to/bun", "/path/to/script.js", "arg1", "arg2"]
// 获取脚本参数
const args = process.argv.slice(2);
console.log(args);
// 当前工作目录
console.log(process.cwd());
// 切换工作目录
process.chdir("/tmp");
标准流 #
typescript
// 标准输入
process.stdin.on("data", (chunk) => {
console.log("Received:", chunk.toString());
});
// 标准输出
process.stdout.write("Hello, stdout!\n");
// 标准错误
process.stderr.write("Error message\n");
// 快捷方法
console.log("To stdout");
console.error("To stderr");
进程退出 #
typescript
// 正常退出
process.exit(0);
// 异常退出
process.exit(1);
// 设置退出码(不立即退出)
process.exitCode = 1;
// 退出事件
process.on("exit", (code) => {
console.log(`Process exiting with code ${code}`);
});
进程事件 #
typescript
// 未捕获异常
process.on("uncaughtException", (error) => {
console.error("Uncaught exception:", error);
process.exit(1);
});
// 未处理的 Promise 拒绝
process.on("unhandledRejection", (reason, promise) => {
console.error("Unhandled rejection:", reason);
});
// 警告
process.on("warning", (warning) => {
console.warn("Warning:", warning);
});
// 信号处理
process.on("SIGINT", () => {
console.log("Received SIGINT");
process.exit(0);
});
process.on("SIGTERM", () => {
console.log("Received SIGTERM");
process.exit(0);
});
Bun.spawn() #
基本用法 #
typescript
// 创建子进程
const proc = Bun.spawn(["echo", "Hello, Bun!"]);
// 等待进程结束
await proc.exited;
// 获取退出码
console.log(proc.exitCode);
捕获输出 #
typescript
const proc = Bun.spawn(["echo", "Hello"], {
stdout: "pipe",
});
// 读取输出
const text = await new Response(proc.stdout).text();
console.log(text); // "Hello\n"
提供输入 #
typescript
const proc = Bun.spawn(["cat"], {
stdin: "pipe",
stdout: "pipe",
});
// 写入输入
proc.stdin.write("Hello from stdin");
proc.stdin.end();
// 读取输出
const output = await new Response(proc.stdout).text();
console.log(output); // "Hello from stdin"
环境变量 #
typescript
const proc = Bun.spawn(["env"], {
env: {
...process.env,
MY_VAR: "custom_value",
},
stdout: "pipe",
});
const output = await new Response(proc.stdout).text();
console.log(output);
工作目录 #
typescript
const proc = Bun.spawn(["pwd"], {
cwd: "/tmp",
stdout: "pipe",
});
const output = await new Response(proc.stdout).text();
console.log(output); // "/tmp"
生命周期 #
typescript
const proc = Bun.spawn(["sleep", "10"]);
// 检查是否运行中
console.log(proc.killed); // false
// 等待退出
const exitPromise = proc.exited;
// 终止进程
proc.kill();
// 使用信号
proc.kill("SIGTERM");
proc.kill("SIGKILL");
await exitPromise;
console.log(proc.exitCode);
完整示例 #
typescript
async function runCommand(cmd: string, args: string[] = []) {
const proc = Bun.spawn([cmd, ...args], {
stdout: "pipe",
stderr: "pipe",
});
const [stdout, stderr] = await Promise.all([
new Response(proc.stdout).text(),
new Response(proc.stderr).text(),
]);
await proc.exited;
return {
exitCode: proc.exitCode,
stdout,
stderr,
};
}
const result = await runCommand("ls", ["-la"]);
console.log(result.stdout);
Shell 命令 (Bun.$) #
基本用法 #
typescript
import { $ } from "bun";
// 执行命令
await $`echo "Hello, Bun!"`;
// 获取输出
const result = await $`ls -la`;
console.log(result.text());
// 获取 JSON 输出
const json = await $`echo '{"name":"Bun"}'`.json();
console.log(json);
命令输出 #
typescript
// 文本输出
const text = await $`echo "Hello"`.text();
console.log(text);
// 行数组
const lines = await $`ls`.lines();
console.log(lines);
// Buffer
const buffer = await $`cat /etc/hosts`.buffer();
// JSON
const data = await $`echo '{"key":"value"}'`.json();
命令链 #
typescript
// 管道
const result = await $`echo "hello" | tr 'a-z' 'A-Z'`;
console.log(result.text()); // "HELLO"
// 链式命令
await $`mkdir -p dist && cp -r src/* dist/`;
环境变量 #
typescript
// 设置环境变量
await $`echo $MY_VAR`.env({ MY_VAR: "hello" });
// 使用当前环境
await $`echo $HOME`.env(process.env);
工作目录 #
typescript
// 设置工作目录
await $`pwd`.cwd("/tmp");
// 链式调用
await $`pwd`.cwd("/tmp").env({ MY_VAR: "value" });
错误处理 #
typescript
try {
await $`exit 1`;
} catch (error) {
console.error("Command failed:", error);
}
// 忽略错误
await $`maybe-fails || true`;
输入重定向 #
typescript
// 从文件输入
await $`cat < input.txt`;
// 从字符串输入
await $`cat`.stdin("Hello from stdin");
// 从 Buffer 输入
const buffer = new TextEncoder().encode("Hello");
await $`cat`.stdin(buffer);
输出重定向 #
typescript
// 输出到文件
await $`echo "Hello" > output.txt`;
// 追加输出
await $`echo "World" >> output.txt`;
// 重定向 stderr
await $`some-command 2>&1`;
交互式命令 #
typescript
// 不捕获输出(直接输出到终端)
await $`vim file.txt`.quiet();
// 实时输出
const proc = $`npm install`;
for await (const line of proc.lines()) {
console.log(line);
}
进程池 #
并行执行 #
typescript
async function runParallel(commands: string[][]) {
const processes = commands.map((cmd) => Bun.spawn(cmd, { stdout: "pipe" }));
const results = await Promise.all(
processes.map(async (proc) => {
const output = await new Response(proc.stdout).text();
await proc.exited;
return { exitCode: proc.exitCode, output };
})
);
return results;
}
const results = await runParallel([
["echo", "task1"],
["echo", "task2"],
["echo", "task3"],
]);
console.log(results);
限制并发 #
typescript
async function runWithConcurrency(
commands: string[][],
concurrency: number
) {
const results: Array<{ exitCode: number; output: string }> = [];
for (let i = 0; i < commands.length; i += concurrency) {
const batch = commands.slice(i, i + concurrency);
const batchResults = await Promise.all(
batch.map(async (cmd) => {
const proc = Bun.spawn(cmd, { stdout: "pipe" });
const output = await new Response(proc.stdout).text();
await proc.exited;
return { exitCode: proc.exitCode!, output };
})
);
results.push(...batchResults);
}
return results;
}
实用工具 #
执行脚本 #
typescript
async function runScript(script: string, args: string[] = []) {
const proc = Bun.spawn(["bun", "run", script, ...args], {
stdout: "pipe",
stderr: "pipe",
});
const [stdout, stderr] = await Promise.all([
new Response(proc.stdout).text(),
new Response(proc.stderr).text(),
]);
await proc.exited;
if (proc.exitCode !== 0) {
throw new Error(`Script failed: ${stderr}`);
}
return stdout;
}
执行 Git 命令 #
typescript
async function git(command: string, ...args: string[]) {
const proc = Bun.spawn(["git", command, ...args], {
stdout: "pipe",
stderr: "pipe",
});
const [stdout, stderr] = await Promise.all([
new Response(proc.stdout).text(),
new Response(proc.stderr).text(),
]);
await proc.exited;
return { stdout, stderr, exitCode: proc.exitCode };
}
// 使用
const { stdout } = await git("status", "--short");
console.log(stdout);
const { stdout: log } = await git("log", "--oneline", "-10");
console.log(log);
执行 npm/bun 命令 #
typescript
async function install(packages: string[], dev = false) {
const args = ["add", ...packages];
if (dev) args.push("--dev");
const proc = Bun.spawn(["bun", ...args], {
stdout: "inherit",
stderr: "inherit",
});
await proc.exited;
return proc.exitCode === 0;
}
await install(["react", "react-dom"]);
await install(["typescript"], true);
进程监控 #
typescript
function monitorProcess(proc: ReturnType<typeof Bun.spawn>) {
const startTime = Date.now();
proc.exited.then(() => {
const duration = Date.now() - startTime;
console.log(`Process exited with code ${proc.exitCode} after ${duration}ms`);
});
return proc;
}
const proc = monitorProcess(Bun.spawn(["sleep", "5"]));
守护进程 #
后台运行 #
typescript
function daemonize(command: string[]) {
const proc = Bun.spawn(command, {
detached: true,
stdin: "ignore",
stdout: "ignore",
stderr: "ignore",
});
proc.unref();
return proc.pid;
}
const pid = daemonize(["bun", "run", "server.ts"]);
console.log(`Started daemon with PID ${pid}`);
进程管理器 #
typescript
class ProcessManager {
private processes: Map<string, ReturnType<typeof Bun.spawn>> = new Map();
start(name: string, command: string[]) {
if (this.processes.has(name)) {
throw new Error(`Process ${name} already running`);
}
const proc = Bun.spawn(command, {
stdout: "pipe",
stderr: "pipe",
});
this.processes.set(name, proc);
console.log(`Started ${name} with PID ${proc.pid}`);
proc.exited.then(() => {
this.processes.delete(name);
console.log(`${name} exited`);
});
return proc;
}
stop(name: string) {
const proc = this.processes.get(name);
if (proc) {
proc.kill();
this.processes.delete(name);
console.log(`Stopped ${name}`);
}
}
list() {
return [...this.processes.keys()];
}
stopAll() {
for (const name of this.processes.keys()) {
this.stop(name);
}
}
}
const pm = new ProcessManager();
pm.start("server", ["bun", "run", "server.ts"]);
pm.start("worker", ["bun", "run", "worker.ts"]);
console.log(pm.list());
下一步 #
现在你已经了解了 Bun 的进程管理功能,接下来学习 包管理器 深入了解 Bun 的包管理功能。
最后更新:2026-03-29