子进程


【Child process】

源代码: lib/child_process.js

node:child_process 模块提供了以类似于 popen(3) 的方式生成子进程的能力,但并不完全相同。这一功能主要由 child_process.spawn() 函数提供:

【The node:child_process module provides the ability to spawn subprocesses in a manner that is similar, but not identical, to popen(3). This capability is primarily provided by the child_process.spawn() function:】

const { spawn } = require('node:child_process');
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.error(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});import { spawn } from 'node:child_process';
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.error(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

默认情况下,会在父 Node.js 进程和生成的子进程之间建立 stdinstdoutstderr 管道。这些管道的容量有限(并且因平台而异)。如果子进程向 stdout 写入的数据超过了该限制,但输出未被捕获,子进程将会阻塞,等待管道缓冲区接受更多数据。这与 shell 中管道的行为完全相同。如果输出不会被使用,请使用 { stdio: 'ignore' } 选项。

【By default, pipes for stdin, stdout, and stderr are established between the parent Node.js process and the spawned subprocess. These pipes have limited (and platform-specific) capacity. If the subprocess writes to stdout in excess of that limit without the output being captured, the subprocess blocks, waiting for the pipe buffer to accept more data. This is identical to the behavior of pipes in the shell. Use the { stdio: 'ignore' } option if the output will not be consumed.】

如果 options 对象中包含 env,则命令查找将使用 options.env.PATH 环境变量。否则,将使用 process.env.PATH。如果设置了 options.env 但未包含 PATH,则在 Unix 系统上会在默认搜索路径 /usr/bin:/bin 上进行查找(参见操作系统手册中的 execvpe/execvp),在 Windows 系统上则使用当前进程的环境变量 PATH

【The command lookup is performed using the options.env.PATH environment variable if env is in the options object. Otherwise, process.env.PATH is used. If options.env is set without PATH, lookup on Unix is performed on a default search path search of /usr/bin:/bin (see your operating system's manual for execvpe/execvp), on Windows the current processes environment variable PATH is used.】

在 Windows 上,环境变量不区分大小写。Node.js 对 env 键进行字典顺序排序,并使用第一个大小写不敏感匹配的键。只有第一个(按字典顺序)条目会被传递给子进程。当向 env 选项传递包含同一键的多个变体(例如 PATHPath)的对象时,这可能会在 Windows 上导致问题。

【On Windows, environment variables are case-insensitive. Node.js lexicographically sorts the env keys and uses the first one that case-insensitively matches. Only first (in lexicographic order) entry will be passed to the subprocess. This might lead to issues on Windows when passing objects to the env option that have multiple variants of the same key, such as PATH and Path.】

child_process.spawn() 方法异步地创建子进程,而不会阻塞 Node.js 事件循环。child_process.spawnSync() 函数以同步的方式提供等效功能,会阻塞事件循环,直到创建的进程退出或被终止。

【The child_process.spawn() method spawns the child process asynchronously, without blocking the Node.js event loop. The child_process.spawnSync() function provides equivalent functionality in a synchronous manner that blocks the event loop until the spawned process either exits or is terminated.】

为了方便,node:child_process 模块提供了一些同步和异步的替代方法,用于 child_process.spawn()child_process.spawnSync()。这些替代方法中的每一个都是基于 child_process.spawn()child_process.spawnSync() 实现的。

【For convenience, the node:child_process module provides a handful of synchronous and asynchronous alternatives to child_process.spawn() and child_process.spawnSync(). Each of these alternatives are implemented on top of child_process.spawn() or child_process.spawnSync().】

对于某些使用场景,例如自动化 shell 脚本,同步对应物 可能更为方便。然而,在许多情况下,同步方法可能会对性能产生显著影响,因为在生成的进程完成时会阻塞事件循环。

【For certain use cases, such as automating shell scripts, the synchronous counterparts may be more convenient. In many cases, however, the synchronous methods can have significant impact on performance due to stalling the event loop while spawned processes complete.】