Node.js v18.19.0 文档


子进程#

Child process

稳定性: 2 - 稳定的

Stability: 2 - Stable

源代码: 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}`);
}); 

默认情况下,会在父 Node.js 进程和衍生的子进程之间建立 stdinstdoutstderr 的管道。这些管道的容量有限(且特定于平台)。如果子进程在没有捕获输出的情况下写入标准输出超过该限制,则子进程会阻塞等待管道缓冲区接受更多数据。这与 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.

如果 envoptions 对象中,则使用 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.

异步进程创建#

Asynchronous process creation

child_process.spawn()child_process.fork()child_process.exec()child_process.execFile() 方法都遵循其他 Node.js API 典型的惯用异步编程模式。

The child_process.spawn(), child_process.fork(), child_process.exec(), and child_process.execFile() methods all follow the idiomatic asynchronous programming pattern typical of other Node.js APIs.

每个方法都返回 ChildProcess 实例。这些对象实现了 Node.js EventEmitter API,允许父进程注册在子进程的生命周期中发生某些事件时调用的监听器函数。

Each of the methods returns a ChildProcess instance. These objects implement the Node.js EventEmitter API, allowing the parent process to register listener functions that are called when certain events occur during the life cycle of the child process.

child_process.exec()child_process.execFile() 方法还允许指定可选的 callback 函数,其在子进程终止时调用。

The child_process.exec() and child_process.execFile() methods additionally allow for an optional callback function to be specified that is invoked when the child process terminates.

在 Windows 上生成 .bat.cmd 文件#

Spawning .bat and .cmd files on Windows

child_process.exec()child_process.execFile() 之间区别的重要性可能因平台而异。在 Unix 类型的操作系统(Unix、Linux、macOS)上,child_process.execFile() 可以更高效,因为它默认不衍生 shell。但是,在 Windows 上,.bat.cmd 文件在没有终端的情况下无法自行执行,因此无法使用 child_process.execFile() 启动。在 Windows 上运行时,.bat.cmd 文件可以使用具有 shell 选项集的 child_process.spawn()、使用 child_process.exec()、或通过衍生 cmd.exe 并将 .bat.cmd 文件作为参数传入(这也是 shell 选项和 child_process.exec() 所做的)来调用。在任何情况下,如果脚本文件名包含空格,则需要加上引号。

The importance of the distinction between child_process.exec() and child_process.execFile() can vary based on platform. On Unix-type operating systems (Unix, Linux, macOS) child_process.execFile() can be more efficient because it does not spawn a shell by default. On Windows, however, .bat and .cmd files are not executable on their own without a terminal, and therefore cannot be launched using child_process.execFile(). When running on Windows, .bat and .cmd files can be invoked using child_process.spawn() with the shell option set, with child_process.exec(), or by spawning cmd.exe and passing the .bat or .cmd file as an argument (which is what the shell option and child_process.exec() do). In any case, if the script filename contains spaces it needs to be quoted.

// On Windows Only...
const { spawn } = require('node:child_process');
const bat = spawn('cmd.exe', ['/c', 'my.bat']);

bat.stdout.on('data', (data) => {
  console.log(data.toString());
});

bat.stderr.on('data', (data) => {
  console.error(data.toString());
});

bat.on('exit', (code) => {
  console.log(`Child exited with code ${code}`);
}); 
// OR...
const { exec, spawn } = require('node:child_process');
exec('my.bat', (err, stdout, stderr) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(stdout);
});

// Script with spaces in the filename:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });
// or:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
  // ...
}); 

child_process.exec(command[, options][, callback])#

  • command <string> 要运行的命令,参数以空格分隔。

    command <string> The command to run, with space-separated arguments.

  • options <Object>

    • cwd <string> | <URL> 子进程的当前工作目录。默认值:process.cwd()

      cwd <string> | <URL> Current working directory of the child process. Default: process.cwd().

    • env <Object> 环境变量键值对。默认值:process.env

      env <Object> Environment key-value pairs. Default: process.env.

    • encoding <string> 默认值:'utf8'

      encoding <string> Default: 'utf8'

    • shell <string> 用于执行命令的 shell。参见 Shell 要求默认 Windows shell。默认值:Unix 上为 '/bin/sh',Windows 上为 process.env.ComSpec

      shell <string> Shell to execute the command with. See Shell requirements and Default Windows shell. Default: '/bin/sh' on Unix, process.env.ComSpec on Windows.

    • signal <AbortSignal> 允许使用 AbortSignal 中止子进程。

      signal <AbortSignal> allows aborting the child process using an AbortSignal.

    • timeout <number> 默认值:0

      timeout <number> Default: 0

    • maxBuffer <number> 标准输出或标准错误上允许的最大数据量(以字节为单位)。如果超过,则子进程将终止并截断任何输出。请参阅 maxBuffer 和 Unicode 的警告。默认值:1024 * 1024

      maxBuffer <number> Largest amount of data in bytes allowed on stdout or stderr. If exceeded, the child process is terminated and any output is truncated. See caveat at maxBuffer and Unicode. Default: 1024 * 1024.

    • killSignal <string> | <integer> 默认值:'SIGTERM'

      killSignal <string> | <integer> Default: 'SIGTERM'

    • uid <number> 设置进程的用户身份(请参阅 setuid(2))。

      uid <number> Sets the user identity of the process (see setuid(2)).

    • gid <number> 设置进程的组标识(请参阅 setgid(2))。

      gid <number> Sets the group identity of the process (see setgid(2)).

    • windowsHide <boolean> 隐藏通常在 Windows 系统上创建的子进程控制台窗口。默认值:false

      windowsHide <boolean> Hide the subprocess console window that would normally be created on Windows systems. Default: false.

  • callback <Function> 当进程终止时调用输出。

    callback <Function> called with the output when process terminates.

  • 返回:<ChildProcess>

    Returns: <ChildProcess>

衍生 shell,然后在该 shell 中执行 command,缓冲任何生成的输出。传递给 exec 函数的 command 字符串由 shell 直接处理,特殊字符(根据 shell 有所不同)需要进行相应处理:

Spawns a shell then executes the command within that shell, buffering any generated output. The command string passed to the exec function is processed directly by the shell and special characters (vary based on shell) need to be dealt with accordingly:

const { exec } = require('node:child_process');

exec('"/path/to/test file/test.sh" arg1 arg2');
// Double quotes are used so that the space in the path is not interpreted as
// a delimiter of multiple arguments.

exec('echo "The \\$HOME variable is $HOME"');
// The $HOME variable is escaped in the first instance, but not in the second. 

切勿将未经处理的用户输入传递给此函数。任何包含 shell 元字符的输入都可用于触发任意命令执行。

Never pass unsanitized user input to this function. Any input containing shell metacharacters may be used to trigger arbitrary command execution.

如果提供了 callback 函数,则使用参数 (error, stdout, stderr) 调用它。成功后,error 将是 null。出错时,error 将是 Error 的实例。error.code 属性将是进程的退出码。按照惯例,除 0 之外的任何退出码都表示错误。error.signal 将是终止进程的信号。

If a callback function is provided, it is called with the arguments (error, stdout, stderr). On success, error will be null. On error, error will be an instance of Error. The error.code property will be the exit code of the process. By convention, any exit code other than 0 indicates an error. error.signal will be the signal that terminated the process.

传给回调的 stdoutstderr 参数将包含子进程的标准输出和标准错误的输出。默认情况下,Node.js 会将输出解码为 UTF-8 并将字符串传给回调。encoding 选项可用于指定用于解码标准输出和标准错误的输出的字符编码。如果 encoding'buffer' 或无法识别的字符编码,则 Buffer 对象将被传给回调。

The stdout and stderr arguments passed to the callback will contain the stdout and stderr output of the child process. By default, Node.js will decode the output as UTF-8 and pass strings to the callback. The encoding option can be used to specify the character encoding used to decode the stdout and stderr output. If encoding is 'buffer', or an unrecognized character encoding, Buffer objects will be passed to the callback instead.

const { exec } = require('node:child_process');
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
  if (error) {
    console.error(`exec error: ${error}`);
    return;
  }
  console.log(`stdout: ${stdout}`);
  console.error(`stderr: ${stderr}`);
}); 

如果 timeout 大于 0,则如果子进程运行时间超过 timeout 毫秒,父进程将发送由 killSignal 属性(默认为 'SIGTERM')标识的信号。

If timeout is greater than 0, the parent will send the signal identified by the killSignal property (the default is 'SIGTERM') if the child runs longer than timeout milliseconds.

exec(3) POSIX 系统调用不同,child_process.exec() 不会替换现有进程,而是使用 shell 来执行命令。

Unlike the exec(3) POSIX system call, child_process.exec() does not replace the existing process and uses a shell to execute the command.

如果此方法作为其 util.promisify() 版本被调用,则其将为具有 stdoutstderr 属性的 Object 返回 Promise。返回的 ChildProcess 实例作为 child 属性附加到 Promise。如果出现错误(包括任何导致退出码不是 0 的错误),则将返回被拒绝的 promise,其具有与回调中给定相同的 error 对象,但有两个额外的属性 stdoutstderr

If this method is invoked as its util.promisify()ed version, it returns a Promise for an Object with stdout and stderr properties. The returned ChildProcess instance is attached to the Promise as a child property. In case of an error (including any error resulting in an exit code other than 0), a rejected promise is returned, with the same error object given in the callback, but with two additional properties stdout and stderr.

const util = require('node:util');
const exec = util.promisify(require('node:child_process').exec);

async function lsExample() {
  const { stdout, stderr } = await exec('ls');
  console.log('stdout:', stdout);
  console.error('stderr:', stderr);
}
lsExample(); 

如果启用了 signal 选项,则在相应的 AbortController 上调用 .abort() 与在子进程上调用 .kill() 类似,只是传给回调的错误将是 AbortError

If the signal option is enabled, calling .abort() on the corresponding AbortController is similar to calling .kill() on the child process except the error passed to the callback will be an AbortError:

const { exec } = require('node:child_process');
const controller = new AbortController();
const { signal } = controller;
const child = exec('grep ssh', { signal }, (error) => {
  console.error(error); // an AbortError
});
controller.abort(); 

child_process.execFile(file[, args][, options][, callback])#

  • file <string> 要运行的可执行文件的名称或路径。

    file <string> The name or path of the executable file to run.

  • args <string[]> 字符串参数列表。

    args <string[]> List of string arguments.

  • options <Object>

    • cwd <string> | <URL> 子进程的当前工作目录。

      cwd <string> | <URL> Current working directory of the child process.

    • env <Object> 环境变量键值对。默认值:process.env

      env <Object> Environment key-value pairs. Default: process.env.

    • encoding <string> 默认值:'utf8'

      encoding <string> Default: 'utf8'

    • timeout <number> 默认值:0

      timeout <number> Default: 0

    • maxBuffer <number> 标准输出或标准错误上允许的最大数据量(以字节为单位)。如果超过,则子进程将终止并截断任何输出。请参阅 maxBuffer 和 Unicode 的警告。默认值:1024 * 1024

      maxBuffer <number> Largest amount of data in bytes allowed on stdout or stderr. If exceeded, the child process is terminated and any output is truncated. See caveat at maxBuffer and Unicode. Default: 1024 * 1024.

    • killSignal <string> | <integer> 默认值:'SIGTERM'

      killSignal <string> | <integer> Default: 'SIGTERM'

    • uid <number> 设置进程的用户身份(请参阅 setuid(2))。

      uid <number> Sets the user identity of the process (see setuid(2)).

    • gid <number> 设置进程的组标识(请参阅 setgid(2))。

      gid <number> Sets the group identity of the process (see setgid(2)).

    • windowsHide <boolean> 隐藏通常在 Windows 系统上创建的子进程控制台窗口。默认值:false

      windowsHide <boolean> Hide the subprocess console window that would normally be created on Windows systems. Default: false.

    • windowsVerbatimArguments <boolean> 在 Windows 上不为参数加上引号或转义。在 Unix 上被忽略。默认值:false

      windowsVerbatimArguments <boolean> No quoting or escaping of arguments is done on Windows. Ignored on Unix. Default: false.

    • shell <boolean> | <string> 如果是 true,则在 shell 内运行 command。在 Unix 上使用 '/bin/sh',在 Windows 上使用 process.env.ComSpec。可以将不同的 shell 指定为字符串。参见 Shell 要求默认 Windows shell。默认值:false(无壳)。

      shell <boolean> | <string> If true, runs command inside of a shell. Uses '/bin/sh' on Unix, and process.env.ComSpec on Windows. A different shell can be specified as a string. See Shell requirements and Default Windows shell. Default: false (no shell).

    • signal <AbortSignal> 允许使用 AbortSignal 中止子进程。

      signal <AbortSignal> allows aborting the child process using an AbortSignal.

  • callback <Function> 进程终止时使用输出调用。

    callback <Function> Called with the output when process terminates.

  • 返回:<ChildProcess>

    Returns: <ChildProcess>

child_process.execFile() 函数与 child_process.exec() 类似,不同之处在于它默认不衍生 shell。而是,指定的可执行文件 file 直接作为新进程衍生,使其比 child_process.exec() 略有效率。

The child_process.execFile() function is similar to child_process.exec() except that it does not spawn a shell by default. Rather, the specified executable file is spawned directly as a new process making it slightly more efficient than child_process.exec().

支持与 child_process.exec() 相同的选项。由于未衍生 shell,因此不支持 I/O 重定向和文件通配等行为。

The same options as child_process.exec() are supported. Since a shell is not spawned, behaviors such as I/O redirection and file globbing are not supported.

const { execFile } = require('node:child_process');
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
  if (error) {
    throw error;
  }
  console.log(stdout);
}); 

传给回调的 stdoutstderr 参数将包含子进程的标准输出和标准错误的输出。默认情况下,Node.js 会将输出解码为 UTF-8 并将字符串传给回调。encoding 选项可用于指定用于解码标准输出和标准错误的输出的字符编码。如果 encoding'buffer' 或无法识别的字符编码,则 Buffer 对象将被传给回调。

The stdout and stderr arguments passed to the callback will contain the stdout and stderr output of the child process. By default, Node.js will decode the output as UTF-8 and pass strings to the callback. The encoding option can be used to specify the character encoding used to decode the stdout and stderr output. If encoding is 'buffer', or an unrecognized character encoding, Buffer objects will be passed to the callback instead.

如果此方法作为其 util.promisify() 版本被调用,则其将为具有 stdoutstderr 属性的 Object 返回 Promise。返回的 ChildProcess 实例作为 child 属性附加到 Promise。如果出现错误(包括任何导致退出码不是 0 的错误),则将返回被拒绝的 promise,其具有与回调中给定相同的 error 对象,但有两个额外的属性 stdoutstderr

If this method is invoked as its util.promisify()ed version, it returns a Promise for an Object with stdout and stderr properties. The returned ChildProcess instance is attached to the Promise as a child property. In case of an error (including any error resulting in an exit code other than 0), a rejected promise is returned, with the same error object given in the callback, but with two additional properties stdout and stderr.

const util = require('node:util');
const execFile = util.promisify(require('node:child_process').execFile);
async function getVersion() {
  const { stdout } = await execFile('node', ['--version']);
  console.log(stdout);
}
getVersion(); 

如果启用了 shell 选项,请勿将未经处理的用户输入传递给此函数。任何包含 shell 元字符的输入都可用于触发任意命令执行。

If the shell option is enabled, do not pass unsanitized user input to this function. Any input containing shell metacharacters may be used to trigger arbitrary command execution.

如果启用了 signal 选项,则在相应的 AbortController 上调用 .abort() 与在子进程上调用 .kill() 类似,只是传给回调的错误将是 AbortError

If the signal option is enabled, calling .abort() on the corresponding AbortController is similar to calling .kill() on the child process except the error passed to the callback will be an AbortError:

const { execFile } = require('node:child_process');
const controller = new AbortController();
const { signal } = controller;
const child = execFile('node', ['--version'], { signal }, (error) => {
  console.error(error); // an AbortError
});
controller.abort(); 

child_process.fork(modulePath[, args][, options])#

  • modulePath <string> | <URL> 要在子进程中运行的模块。

    modulePath <string> | <URL> The module to run in the child.

  • args <string[]> 字符串参数列表。

    args <string[]> List of string arguments.

  • options <Object>

    • cwd <string> | <URL> 子进程的当前工作目录。

      cwd <string> | <URL> Current working directory of the child process.

    • detached <boolean> 准备子进程独立于其父进程运行。具体行为取决于平台,参见 options.detached

      detached <boolean> Prepare child to run independently of its parent process. Specific behavior depends on the platform, see options.detached).

    • env <Object> 环境变量键值对。默认值:process.env

      env <Object> Environment key-value pairs. Default: process.env.

    • execPath <string> 用于创建子进程的可执行文件。

      execPath <string> Executable used to create the child process.

    • execArgv <string[]> 传给可执行文件的字符串参数列表。默认值:process.execArgv

      execArgv <string[]> List of string arguments passed to the executable. Default: process.execArgv.

    • gid <number> 设置进程的组标识(请参阅 setgid(2))。

      gid <number> Sets the group identity of the process (see setgid(2)).

    • serialization <string> 指定用于在进程之间发送消息的序列化类型。可能的值为 'json''advanced'。有关详细信息,请参阅 高级序列化。默认值:'json'

      serialization <string> Specify the kind of serialization used for sending messages between processes. Possible values are 'json' and 'advanced'. See Advanced serialization for more details. Default: 'json'.

    • signal <AbortSignal> 允许使用中止信号关闭子进程。

      signal <AbortSignal> Allows closing the child process using an AbortSignal.

    • killSignal <string> | <integer> 当衍生的进程将被超时或中止信号杀死时要使用的信号值。默认值:'SIGTERM'

      killSignal <string> | <integer> The signal value to be used when the spawned process will be killed by timeout or abort signal. Default: 'SIGTERM'.

    • silent <boolean> 如果为 true,则子进程的标准输入、标准输出和标准错误将通过管道传输到父进程,否则它们将从父进程继承,有关详细信息,请参阅 child_process.spawn()stdio'pipe''inherit' 选项。默认值:false

      silent <boolean> If true, stdin, stdout, and stderr of the child will be piped to the parent, otherwise they will be inherited from the parent, see the 'pipe' and 'inherit' options for child_process.spawn()'s stdio for more details. Default: false.

    • stdio <Array> | <string> 参见 child_process.spawn()stdio。提供此选项时,它会覆盖 silent。如果使用数组变体,则它必须恰好包含一个值为 'ipc' 的条目,否则将抛出错误。例如 [0, 1, 2, 'ipc']

      stdio <Array> | <string> See child_process.spawn()'s stdio. When this option is provided, it overrides silent. If the array variant is used, it must contain exactly one item with value 'ipc' or an error will be thrown. For instance [0, 1, 2, 'ipc'].

    • uid <number> 设置进程的用户身份(请参阅 setuid(2))。

      uid <number> Sets the user identity of the process (see setuid(2)).

    • windowsVerbatimArguments <boolean> 在 Windows 上不为参数加上引号或转义。在 Unix 上被忽略。默认值:false

      windowsVerbatimArguments <boolean> No quoting or escaping of arguments is done on Windows. Ignored on Unix. Default: false.

    • timeout <number> 允许进程运行的最长时间(以毫秒为单位)。默认值:undefined

      timeout <number> In milliseconds the maximum amount of time the process is allowed to run. Default: undefined.

  • 返回:<ChildProcess>

    Returns: <ChildProcess>

child_process.fork() 方法是 child_process.spawn() 的特例,专门用于衍生新的 Node.js 进程。与 child_process.spawn() 一样,返回 ChildProcess 对象。返回的 ChildProcess 将有额外的内置通信通道,允许消息在父进程和子进程之间来回传递。详见 subprocess.send()

The child_process.fork() method is a special case of child_process.spawn() used specifically to spawn new Node.js processes. Like child_process.spawn(), a ChildProcess object is returned. The returned ChildProcess will have an additional communication channel built-in that allows messages to be passed back and forth between the parent and child. See subprocess.send() for details.

请记住,衍生的 Node.js 子进程独立于父进程,除了两者之间建立的 IPC 通信通道。每个进程都有自己的内存,具有自己的 V8 实例。由于需要额外的资源分配,不建议衍生大量子 Node.js 进程。

Keep in mind that spawned Node.js child processes are independent of the parent with exception of the IPC communication channel that is established between the two. Each process has its own memory, with their own V8 instances. Because of the additional resource allocations required, spawning a large number of child Node.js processes is not recommended.

默认情况下,child_process.fork() 将使用父进程的 process.execPath 衍生新的 Node.js 实例。options 对象中的 execPath 属性允许使用替代的执行路径。

By default, child_process.fork() will spawn new Node.js instances using the process.execPath of the parent process. The execPath property in the options object allows for an alternative execution path to be used.

使用自定义 execPath 启动的 Node.js 进程将使用在子进程上使用环境变量 NODE_CHANNEL_FD 标识的文件描述符与父进程通信。

Node.js processes launched with a custom execPath will communicate with the parent process using the file descriptor (fd) identified using the environment variable NODE_CHANNEL_FD on the child process.

fork(2) POSIX 系统调用不同,child_process.fork() 不会克隆当前进程。

Unlike the fork(2) POSIX system call, child_process.fork() does not clone the current process.

child_process.fork() 不支持 child_process.spawn() 中可用的 shell 选项,如果设置将被忽略。

The shell option available in child_process.spawn() is not supported by child_process.fork() and will be ignored if set.

如果启用了 signal 选项,则在相应的 AbortController 上调用 .abort() 与在子进程上调用 .kill() 类似,只是传给回调的错误将是 AbortError

If the signal option is enabled, calling .abort() on the corresponding AbortController is similar to calling .kill() on the child process except the error passed to the callback will be an AbortError:

if (process.argv[2] === 'child') {
  setTimeout(() => {
    console.log(`Hello from ${process.argv[2]}!`);
  }, 1_000);
} else {
  const { fork } = require('node:child_process');
  const controller = new AbortController();
  const { signal } = controller;
  const child = fork(__filename, ['child'], { signal });
  child.on('error', (err) => {
    // This will be called with err being an AbortError if the controller aborts
  });
  controller.abort(); // Stops the child process
} 

child_process.spawn(command[, args][, options])#

  • command <string> 要运行的命令。

    command <string> The command to run.

  • args <string[]> 字符串参数列表。

    args <string[]> List of string arguments.

  • options <Object>

    • cwd <string> | <URL> 子进程的当前工作目录。

      cwd <string> | <URL> Current working directory of the child process.

    • env <Object> 环境变量键值对。默认值:process.env

      env <Object> Environment key-value pairs. Default: process.env.

    • argv0 <string> 显式设置发送给子进程的 argv[0] 的值。如果未指定,这将设置为 command

      argv0 <string> Explicitly set the value of argv[0] sent to the child process. This will be set to command if not specified.

    • stdio <Array> | <string> 子进程的标准输入输出配置(参见 options.stdio)。

      stdio <Array> | <string> Child's stdio configuration (see options.stdio).

    • detached <boolean> 准备子进程独立于其父进程运行。具体行为取决于平台,参见 options.detached

      detached <boolean> Prepare child to run independently of its parent process. Specific behavior depends on the platform, see options.detached).

    • uid <number> 设置进程的用户身份(请参阅 setuid(2))。

      uid <number> Sets the user identity of the process (see setuid(2)).

    • gid <number> 设置进程的组标识(请参阅 setgid(2))。

      gid <number> Sets the group identity of the process (see setgid(2)).

    • serialization <string> 指定用于在进程之间发送消息的序列化类型。可能的值为 'json''advanced'。有关详细信息,请参阅 高级序列化。默认值:'json'

      serialization <string> Specify the kind of serialization used for sending messages between processes. Possible values are 'json' and 'advanced'. See Advanced serialization for more details. Default: 'json'.

    • shell <boolean> | <string> 如果是 true,则在 shell 内运行 command。在 Unix 上使用 '/bin/sh',在 Windows 上使用 process.env.ComSpec。可以将不同的 shell 指定为字符串。参见 Shell 要求默认 Windows shell。默认值:false(无壳)。

      shell <boolean> | <string> If true, runs command inside of a shell. Uses '/bin/sh' on Unix, and process.env.ComSpec on Windows. A different shell can be specified as a string. See Shell requirements and Default Windows shell. Default: false (no shell).

    • windowsVerbatimArguments <boolean> 在 Windows 上不为参数加上引号或转义。在 Unix 上被忽略。当指定了 shell 并且是 CMD 时,则自动设置为 true。默认值:false

      windowsVerbatimArguments <boolean> No quoting or escaping of arguments is done on Windows. Ignored on Unix. This is set to true automatically when shell is specified and is CMD. Default: false.

    • windowsHide <boolean> 隐藏通常在 Windows 系统上创建的子进程控制台窗口。默认值:false

      windowsHide <boolean> Hide the subprocess console window that would normally be created on Windows systems. Default: false.

    • signal <AbortSignal> 允许使用 AbortSignal 中止子进程。

      signal <AbortSignal> allows aborting the child process using an AbortSignal.

    • timeout <number> 允许进程运行的最长时间(以毫秒为单位)。默认值:undefined

      timeout <number> In milliseconds the maximum amount of time the process is allowed to run. Default: undefined.

    • killSignal <string> | <integer> 当衍生的进程将被超时或中止信号杀死时要使用的信号值。默认值:'SIGTERM'

      killSignal <string> | <integer> The signal value to be used when the spawned process will be killed by timeout or abort signal. Default: 'SIGTERM'.

  • 返回:<ChildProcess>

    Returns: <ChildProcess>

child_process.spawn() 方法使用给定的 commandargs 中的命令行参数衍生新进程。如果省略,args 默认为空数组。

The child_process.spawn() method spawns a new process using the given command, with command-line arguments in args. If omitted, args defaults to an empty array.

如果启用了 shell 选项,请勿将未经处理的用户输入传递给此函数。任何包含 shell 元字符的输入都可用于触发任意命令执行。

If the shell option is enabled, do not pass unsanitized user input to this function. Any input containing shell metacharacters may be used to trigger arbitrary command execution.

第三个参数可用于指定其他选项,具有以下默认值:

A third argument may be used to specify additional options, with these defaults:

const defaults = {
  cwd: undefined,
  env: process.env,
}; 

使用 cwd 指定从中衍生进程的工作目录。如果没有给定,则默认是继承当前工作目录。如果给定,但路径不存在,则子进程会触发 ENOENT 错误并立即退出。当命令不存在时,也会触发 ENOENT

Use cwd to specify the working directory from which the process is spawned. If not given, the default is to inherit the current working directory. If given, but the path does not exist, the child process emits an ENOENT error and exits immediately. ENOENT is also emitted when the command does not exist.

使用 env 指定对新进程可见的环境变量,默认为 process.env

Use env to specify environment variables that will be visible to the new process, the default is process.env.

env 中的 undefined 值将被忽略。

undefined values in env will be ignored.

运行 ls -lh /usr、捕获 stdoutstderr 和退出码的示例:

Example of running ls -lh /usr, capturing stdout, stderr, and the exit code:

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}`);
}); 

示例:一种非常精细的运行 ps ax | grep ssh 的方法

Example: A very elaborate way to run ps ax | grep ssh

const { spawn } = require('node:child_process');
const ps = spawn('ps', ['ax']);
const grep = spawn('grep', ['ssh']);

ps.stdout.on('data', (data) => {
  grep.stdin.write(data);
});

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

ps.on('close', (code) => {
  if (code !== 0) {
    console.log(`ps process exited with code ${code}`);
  }
  grep.stdin.end();
});

grep.stdout.on('data', (data) => {
  console.log(data.toString());
});

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

grep.on('close', (code) => {
  if (code !== 0) {
    console.log(`grep process exited with code ${code}`);
  }
}); 

检查失败 spawn 的示例:

Example of checking for failed spawn:

const { spawn } = require('node:child_process');
const subprocess = spawn('bad_command');

subprocess.on('error', (err) => {
  console.error('Failed to start subprocess.');
}); 

某些平台(macOS、Linux)将使用 argv[0] 的值作为进程标头,而其他平台(Windows、SunOS)将使用 command

Certain platforms (macOS, Linux) will use the value of argv[0] for the process title while others (Windows, SunOS) will use command.

Node.js 在启动时会用 process.execPath 覆盖 argv[0],因此 Node.js 子进程中的 process.argv[0] 不会匹配从父进程传给 spawnargv0 参数。改为使用 process.argv0 属性检索它。

Node.js overwrites argv[0] with process.execPath on startup, so process.argv[0] in a Node.js child process will not match the argv0 parameter passed to spawn from the parent. Retrieve it with the process.argv0 property instead.

如果启用了 signal 选项,则在相应的 AbortController 上调用 .abort() 与在子进程上调用 .kill() 类似,只是传给回调的错误将是 AbortError

If the signal option is enabled, calling .abort() on the corresponding AbortController is similar to calling .kill() on the child process except the error passed to the callback will be an AbortError:

const { spawn } = require('node:child_process');
const controller = new AbortController();
const { signal } = controller;
const grep = spawn('grep', ['ssh'], { signal });
grep.on('error', (err) => {
  // This will be called with err being an AbortError if the controller aborts
});
controller.abort(); // Stops the child process 

options.detached#

在 Windows 上,将 options.detached 设置为 true 可以让子进程在父进程退出后继续运行。子进程将有自己的控制台窗口。一旦为子进程启用,则它就不能被禁用。

On Windows, setting options.detached to true makes it possible for the child process to continue running after the parent exits. The child will have its own console window. Once enabled for a child process, it cannot be disabled.

在非 Windows 平台上,如果 options.detached 设置为 true,则子进程将成为新进程组和会话的领导者。子进程可以在父进程退出后继续运行,不管它们是否分离。有关详细信息,请参阅 setsid(2)

On non-Windows platforms, if options.detached is set to true, the child process will be made the leader of a new process group and session. Child processes may continue running after the parent exits regardless of whether they are detached or not. See setsid(2) for more information.

默认情况下,父进程将等待分离的子进程退出。为了防止父进程等待给定的 subprocess 退出,则使用 subprocess.unref() 方法。这样做会使父进程的事件循环不将子进程包括在其引用计数中,从而允许父进程独立于子进程退出,除非在子进程和父进程之间建立了 IPC 通道。

By default, the parent will wait for the detached child to exit. To prevent the parent from waiting for a given subprocess to exit, use the subprocess.unref() method. Doing so will cause the parent's event loop to not include the child in its reference count, allowing the parent to exit independently of the child, unless there is an established IPC channel between the child and the parent.

当使用 detached 选项启动长时间运行的进程时,进程在父进程退出后不会一直在后台运行,除非提供了未连接到父进程的 stdio 配置。如果继承了父进程的 stdio,则子进程将保持与控制终端的连接。

When using the detached option to start a long-running process, the process will not stay running in the background after the parent exits unless it is provided with a stdio configuration that is not connected to the parent. If the parent's stdio is inherited, the child will remain attached to the controlling terminal.

长时间运行的进程的示例,通过分离并忽略其父进程的 stdio 文件描述符,以忽略父进程的终止:

Example of a long-running process, by detaching and also ignoring its parent stdio file descriptors, in order to ignore the parent's termination:

const { spawn } = require('node:child_process');

const subprocess = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: 'ignore',
});

subprocess.unref(); 

或者,可以将子进程的输出重定向到文件中:

Alternatively one can redirect the child process' output into files:

const fs = require('node:fs');
const { spawn } = require('node:child_process');
const out = fs.openSync('./out.log', 'a');
const err = fs.openSync('./out.log', 'a');

const subprocess = spawn('prg', [], {
  detached: true,
  stdio: [ 'ignore', out, err ],
});

subprocess.unref(); 

options.stdio#

options.stdio 选项用于配置在父进程和子进程之间建立的管道。默认情况下,子进程的标准输入、标准输出和标准错误被重定向到 ChildProcess 对象上相应的 subprocess.stdinsubprocess.stdoutsubprocess.stderr 流。这相当于将 options.stdio 设置为等于 ['pipe', 'pipe', 'pipe']

The options.stdio option is used to configure the pipes that are established between the parent and child process. By default, the child's stdin, stdout, and stderr are redirected to corresponding subprocess.stdin, subprocess.stdout, and subprocess.stderr streams on the ChildProcess object. This is equivalent to setting the options.stdio equal to ['pipe', 'pipe', 'pipe'].

为方便起见,options.stdio 可能是以下字符串之一:

For convenience, options.stdio may be one of the following strings:

  • 'pipe':相当于 ['pipe', 'pipe', 'pipe'](默认)

    'pipe': equivalent to ['pipe', 'pipe', 'pipe'] (the default)

  • 'overlapped':相当于 ['overlapped', 'overlapped', 'overlapped']

    'overlapped': equivalent to ['overlapped', 'overlapped', 'overlapped']

  • 'ignore':相当于 ['ignore', 'ignore', 'ignore']

    'ignore': equivalent to ['ignore', 'ignore', 'ignore']

  • 'inherit':相当于 ['inherit', 'inherit', 'inherit'][0, 1, 2]

    'inherit': equivalent to ['inherit', 'inherit', 'inherit'] or [0, 1, 2]

否则,options.stdio 的值是一个数组,其中每个索引对应于子进程中的文件描述符。文件描述符 0、1 和 2 分别对应于标准输入、标准输出和标准错误。可以指定额外的文件描述符以在父进程和子进程之间创建额外的管道。该值是以下之一:

Otherwise, the value of options.stdio is an array where each index corresponds to an fd in the child. The fds 0, 1, and 2 correspond to stdin, stdout, and stderr, respectively. Additional fds can be specified to create additional pipes between the parent and child. The value is one of the following:

  1. 'pipe':在子进程和父进程之间创建管道。管道的父端作为 subprocess.stdio[fd] 对象上的 child_process 对象的属性公开给父级。为 fds 0、1 和 2 创建的管道也可分别用作 subprocess.stdinsubprocess.stdoutsubprocess.stderr。这些不是实际的 Unix 管道,因此子进程不能通过它们的描述符文件使用它们,例如 /dev/fd/2/dev/stdout

    'pipe': Create a pipe between the child process and the parent process. The parent end of the pipe is exposed to the parent as a property on the child_process object as subprocess.stdio[fd]. Pipes created for fds 0, 1, and 2 are also available as subprocess.stdin, subprocess.stdout and subprocess.stderr, respectively. These are not actual Unix pipes and therefore the child process can not use them by their descriptor files, e.g. /dev/fd/2 or /dev/stdout.

  2. 'overlapped':与 'pipe' 相同,只是在句柄上设置了 FILE_FLAG_OVERLAPPED 标志。这对于子进程的 stdio 句柄上的重叠 I/O 是必需的。有关详细信息,请参阅 文档。这与非 Windows 系统上的 'pipe' 完全相同。

    'overlapped': Same as 'pipe' except that the FILE_FLAG_OVERLAPPED flag is set on the handle. This is necessary for overlapped I/O on the child process's stdio handles. See the docs for more details. This is exactly the same as 'pipe' on non-Windows systems.

  3. 'ipc':创建一个 IPC 通道,用于在父子之间传递消息/文件描述符。一个 ChildProcess 最多可以有一个 IPC stdio 文件描述符。设置此选项可启用 subprocess.send() 方法。如果子进程是 Node.js 进程,IPC 通道的存在将启用 process.send()process.disconnect() 方法,以及子进程中的 'disconnect''message' 事件。

    'ipc': Create an IPC channel for passing messages/file descriptors between parent and child. A ChildProcess may have at most one IPC stdio file descriptor. Setting this option enables the subprocess.send() method. If the child is a Node.js process, the presence of an IPC channel will enable process.send() and process.disconnect() methods, as well as 'disconnect' and 'message' events within the child.

    不支持以 process.send() 以外的任何方式访问 IPC 通道 fd 或将 IPC 通道用于非 Node.js 实例的子进程。

    Accessing the IPC channel fd in any way other than process.send() or using the IPC channel with a child process that is not a Node.js instance is not supported.

  4. 'ignore':指示 Node.js 忽略子项中的 fd。虽然 Node.js 将始终为其生成的进程打开 fds 0、1 和 2,但将 fd 设置为 'ignore' 将导致 Node.js 打开 /dev/null 并将其附加到子进程的 fd。

    'ignore': Instructs Node.js to ignore the fd in the child. While Node.js will always open fds 0, 1, and 2 for the processes it spawns, setting the fd to 'ignore' will cause Node.js to open /dev/null and attach it to the child's fd.

  5. 'inherit':通过相应的 stdio 流传入/传出父进程。在前三个位置,这分别相当于 process.stdinprocess.stdoutprocess.stderr。在任何其他位置,相当于 'ignore'

    'inherit': Pass through the corresponding stdio stream to/from the parent process. In the first three positions, this is equivalent to process.stdin, process.stdout, and process.stderr, respectively. In any other position, equivalent to 'ignore'.

  6. <Stream> 对象:与子进程共享引用 tty、文件、套接字或管道的可读或可写流。流的底层文件描述符在子进程中复制到与 stdio 数组中的索引相对应的 fd。流必须具有底层描述符(文件流只有在 'open' 事件发生后才具有)。

    <Stream> object: Share a readable or writable stream that refers to a tty, file, socket, or a pipe with the child process. The stream's underlying file descriptor is duplicated in the child process to the fd that corresponds to the index in the stdio array. The stream must have an underlying descriptor (file streams do not until the 'open' event has occurred).

  7. 正整数:整数值被解释为在父进程中打开的文件描述符。它与子进程共享,类似于 <Stream> 对象的共享方式。Windows 不支持传递套接字。

    Positive integer: The integer value is interpreted as a file descriptor that is open in the parent process. It is shared with the child process, similar to how <Stream> objects can be shared. Passing sockets is not supported on Windows.

  8. null, undefined:使用默认值。对于 stdio fds 0、1 和 2(换句话说,stdin、stdout 和 stderr),创建了一个管道。对于 fd 3 及更高版本,默认值为 'ignore'

    null, undefined: Use default value. For stdio fds 0, 1, and 2 (in other words, stdin, stdout, and stderr) a pipe is created. For fd 3 and up, the default is 'ignore'.

const { spawn } = require('node:child_process');

// Child will use parent's stdios.
spawn('prg', [], { stdio: 'inherit' });

// Spawn child sharing only stderr.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });

// Open an extra fd=4, to interact with programs presenting a
// startd-style interface.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] }); 

值得注意的是,当父子进程之间建立了 IPC 通道,并且子进程是 Node.js 进程时,子进程将在未引用 IPC 通道(使用 unref())的情况下启动,直到子进程为该子进程注册事件处理程序 'disconnect' 事件或 'message' 事件。这允许子进程正常退出,而进程不会被打开的 IPC 通道保持打开状态。

It is worth noting that when an IPC channel is established between the parent and child processes, and the child is a Node.js process, the child is launched with the IPC channel unreferenced (using unref()) until the child registers an event handler for the 'disconnect' event or the 'message' event. This allows the child to exit normally without the process being held open by the open IPC channel.

在类 Unix 操作系统上,child_process.spawn() 方法在将事件循环与子进程解耦之前同步执行内存操作。具有大量内存占用的应用可能会发现频繁的 child_process.spawn() 调用成为瓶颈。有关详细信息,请参阅 V8 问题 7381

On Unix-like operating systems, the child_process.spawn() method performs memory operations synchronously before decoupling the event loop from the child. Applications with a large memory footprint may find frequent child_process.spawn() calls to be a bottleneck. For more information, see V8 issue 7381.

也可以看看:child_process.exec()child_process.fork()

See also: child_process.exec() and child_process.fork().

同步进程创建#

Synchronous process creation

child_process.spawnSync()child_process.execSync()child_process.execFileSync() 方法是同步的,将阻塞 Node.js 事件循环,暂停执行任何其他代码,直到衍生进程退出。

The child_process.spawnSync(), child_process.execSync(), and child_process.execFileSync() methods are synchronous and will block the Node.js event loop, pausing execution of any additional code until the spawned process exits.

像这样的阻塞调用对于简化通用脚本任务和简化启动时应用配置的加载/处理非常有用。

Blocking calls like these are mostly useful for simplifying general-purpose scripting tasks and for simplifying the loading/processing of application configuration at startup.

child_process.execFileSync(file[, args][, options])#

  • file <string> 要运行的可执行文件的名称或路径。

    file <string> The name or path of the executable file to run.

  • args <string[]> 字符串参数列表。

    args <string[]> List of string arguments.

  • options <Object>

    • cwd <string> | <URL> 子进程的当前工作目录。

      cwd <string> | <URL> Current working directory of the child process.

    • input <string> | <Buffer> | <TypedArray> | <DataView> 将作为标准输入传给衍生进程的值。提供此值将覆盖 stdio[0]

      input <string> | <Buffer> | <TypedArray> | <DataView> The value which will be passed as stdin to the spawned process. Supplying this value will override stdio[0].

    • stdio <string> | <Array> 子进程的标准输入输出配置。除非指定 stdio,否则默认情况下 stderr 将输出到父进程的标准错误。默认值:'pipe'

      stdio <string> | <Array> Child's stdio configuration. stderr by default will be output to the parent process' stderr unless stdio is specified. Default: 'pipe'.

    • env <Object> 环境变量键值对。默认值:process.env

      env <Object> Environment key-value pairs. Default: process.env.

    • uid <number> 设置进程的用户身份(请参阅 setuid(2))。

      uid <number> Sets the user identity of the process (see setuid(2)).

    • gid <number> 设置进程的组标识(请参阅 setgid(2))。

      gid <number> Sets the group identity of the process (see setgid(2)).

    • timeout <number> 允许进程运行的最长时间(以毫秒为单位)。默认值:undefined

      timeout <number> In milliseconds the maximum amount of time the process is allowed to run. Default: undefined.

    • killSignal <string> | <integer> 衍生的进程将被终止时要使用的信号值。默认值:'SIGTERM'

      killSignal <string> | <integer> The signal value to be used when the spawned process will be killed. Default: 'SIGTERM'.

    • maxBuffer <number> 标准输出或标准错误上允许的最大数据量(以字节为单位)。如果超过,则终止子进程。请参阅 maxBuffer 和 Unicode 的警告。默认值:1024 * 1024

      maxBuffer <number> Largest amount of data in bytes allowed on stdout or stderr. If exceeded, the child process is terminated. See caveat at maxBuffer and Unicode. Default: 1024 * 1024.

    • encoding <string> 用于所有标准输入输出的输入和输出的编码。默认值:'buffer'

      encoding <string> The encoding used for all stdio inputs and outputs. Default: 'buffer'.

    • windowsHide <boolean> 隐藏通常在 Windows 系统上创建的子进程控制台窗口。默认值:false

      windowsHide <boolean> Hide the subprocess console window that would normally be created on Windows systems. Default: false.

    • shell <boolean> | <string> 如果是 true,则在 shell 内运行 command。在 Unix 上使用 '/bin/sh',在 Windows 上使用 process.env.ComSpec。可以将不同的 shell 指定为字符串。参见 Shell 要求默认 Windows shell。默认值:false(无壳)。

      shell <boolean> | <string> If true, runs command inside of a shell. Uses '/bin/sh' on Unix, and process.env.ComSpec on Windows. A different shell can be specified as a string. See Shell requirements and Default Windows shell. Default: false (no shell).

  • 返回:<Buffer> | <string> 命令的标准输出。

    Returns: <Buffer> | <string> The stdout from the command.

child_process.execFileSync() 方法通常与 child_process.execFile() 相同,只是该方法在子进程完全关闭之前不会返回。当遇到超时并发送 killSignal 时,该方法将在进程完全退出之前不会返回。

The child_process.execFileSync() method is generally identical to child_process.execFile() with the exception that the method will not return until the child process has fully closed. When a timeout has been encountered and killSignal is sent, the method won't return until the process has completely exited.

如果子进程拦截并处理了 SIGTERM 信号并没有退出,父进程仍然会等待,直到子进程退出。

If the child process intercepts and handles the SIGTERM signal and does not exit, the parent process will still wait until the child process has exited.

如果进程超时或具有非零退出代码,此方法将抛出一个 Error,其中将包含底层 child_process.spawnSync() 的完整结果。

If the process times out or has a non-zero exit code, this method will throw an Error that will include the full result of the underlying child_process.spawnSync().

如果启用了 shell 选项,请勿将未经处理的用户输入传递给此函数。任何包含 shell 元字符的输入都可用于触发任意命令执行。

If the shell option is enabled, do not pass unsanitized user input to this function. Any input containing shell metacharacters may be used to trigger arbitrary command execution.

child_process.execSync(command[, options])#

  • command <string> 要运行的命令。

    command <string> The command to run.

  • options <Object>

    • cwd <string> | <URL> 子进程的当前工作目录。

      cwd <string> | <URL> Current working directory of the child process.

    • input <string> | <Buffer> | <TypedArray> | <DataView> 将作为标准输入传给衍生进程的值。提供此值将覆盖 stdio[0]

      input <string> | <Buffer> | <TypedArray> | <DataView> The value which will be passed as stdin to the spawned process. Supplying this value will override stdio[0].

    • stdio <string> | <Array> 子进程的标准输入输出配置。除非指定 stdio,否则默认情况下 stderr 将输出到父进程的标准错误。默认值:'pipe'

      stdio <string> | <Array> Child's stdio configuration. stderr by default will be output to the parent process' stderr unless stdio is specified. Default: 'pipe'.

    • env <Object> 环境变量键值对。默认值:process.env

      env <Object> Environment key-value pairs. Default: process.env.

    • shell <string> 用于执行命令的 shell。参见 Shell 要求默认 Windows shell。默认值:Unix 上为 '/bin/sh',Windows 上为 process.env.ComSpec

      shell <string> Shell to execute the command with. See Shell requirements and Default Windows shell. Default: '/bin/sh' on Unix, process.env.ComSpec on Windows.

    • uid <number> 设置进程的用户标识。(请参阅 setuid(2))。

      uid <number> Sets the user identity of the process. (See setuid(2)).

    • gid <number> 设置进程的群组标识。(参见 setgid(2))。

      gid <number> Sets the group identity of the process. (See setgid(2)).

    • timeout <number> 允许进程运行的最长时间(以毫秒为单位)。默认值:undefined

      timeout <number> In milliseconds the maximum amount of time the process is allowed to run. Default: undefined.

    • killSignal <string> | <integer> 衍生的进程将被终止时要使用的信号值。默认值:'SIGTERM'

      killSignal <string> | <integer> The signal value to be used when the spawned process will be killed. Default: 'SIGTERM'.

    • maxBuffer <number> 标准输出或标准错误上允许的最大数据量(以字节为单位)。如果超过,则子进程将终止并截断任何输出。请参阅 maxBuffer 和 Unicode 的警告。默认值:1024 * 1024

      maxBuffer <number> Largest amount of data in bytes allowed on stdout or stderr. If exceeded, the child process is terminated and any output is truncated. See caveat at maxBuffer and Unicode. Default: 1024 * 1024.

    • encoding <string> 用于所有标准输入输出的输入和输出的编码。默认值:'buffer'

      encoding <string> The encoding used for all stdio inputs and outputs. Default: 'buffer'.

    • windowsHide <boolean> 隐藏通常在 Windows 系统上创建的子进程控制台窗口。默认值:false

      windowsHide <boolean> Hide the subprocess console window that would normally be created on Windows systems. Default: false.

  • 返回:<Buffer> | <string> 命令的标准输出。

    Returns: <Buffer> | <string> The stdout from the command.

child_process.execSync() 方法通常与 child_process.exec() 相同,只是该方法在子进程完全关闭之前不会返回。当遇到超时并发送 killSignal 时,该方法将在进程完全退出之前不会返回。如果子进程拦截并处理了 SIGTERM 信号没有退出,父进程会一直等到子进程退出。

The child_process.execSync() method is generally identical to child_process.exec() with the exception that the method will not return until the child process has fully closed. When a timeout has been encountered and killSignal is sent, the method won't return until the process has completely exited. If the child process intercepts and handles the SIGTERM signal and doesn't exit, the parent process will wait until the child process has exited.

如果进程超时或具有非零退出代码,则此方法将抛出。Error 对象将包含来自 child_process.spawnSync() 的整个结果。

If the process times out or has a non-zero exit code, this method will throw. The Error object will contain the entire result from child_process.spawnSync().

切勿将未经处理的用户输入传递给此函数。任何包含 shell 元字符的输入都可用于触发任意命令执行。

Never pass unsanitized user input to this function. Any input containing shell metacharacters may be used to trigger arbitrary command execution.

child_process.spawnSync(command[, args][, options])#

  • command <string> 要运行的命令。

    command <string> The command to run.

  • args <string[]> 字符串参数列表。

    args <string[]> List of string arguments.

  • options <Object>

    • cwd <string> | <URL> 子进程的当前工作目录。

      cwd <string> | <URL> Current working directory of the child process.

    • input <string> | <Buffer> | <TypedArray> | <DataView> 将作为标准输入传给衍生进程的值。提供此值将覆盖 stdio[0]

      input <string> | <Buffer> | <TypedArray> | <DataView> The value which will be passed as stdin to the spawned process. Supplying this value will override stdio[0].

    • argv0 <string> 显式设置发送给子进程的 argv[0] 的值。如果未指定,这将设置为 command

      argv0 <string> Explicitly set the value of argv[0] sent to the child process. This will be set to command if not specified.

    • stdio <string> | <Array> 子进程的标准输入输出配置。

      stdio <string> | <Array> Child's stdio configuration.

    • env <Object> 环境变量键值对。默认值:process.env

      env <Object> Environment key-value pairs. Default: process.env.

    • uid <number> 设置进程的用户身份(请参阅 setuid(2))。

      uid <number> Sets the user identity of the process (see setuid(2)).

    • gid <number> 设置进程的组标识(请参阅 setgid(2))。

      gid <number> Sets the group identity of the process (see setgid(2)).

    • timeout <number> 允许进程运行的最长时间(以毫秒为单位)。默认值:undefined

      timeout <number> In milliseconds the maximum amount of time the process is allowed to run. Default: undefined.

    • killSignal <string> | <integer> 衍生的进程将被终止时要使用的信号值。默认值:'SIGTERM'

      killSignal <string> | <integer> The signal value to be used when the spawned process will be killed. Default: 'SIGTERM'.

    • maxBuffer <number> 标准输出或标准错误上允许的最大数据量(以字节为单位)。如果超过,则子进程将终止并截断任何输出。请参阅 maxBuffer 和 Unicode 的警告。默认值:1024 * 1024

      maxBuffer <number> Largest amount of data in bytes allowed on stdout or stderr. If exceeded, the child process is terminated and any output is truncated. See caveat at maxBuffer and Unicode. Default: 1024 * 1024.

    • encoding <string> 用于所有标准输入输出的输入和输出的编码。默认值:'buffer'

      encoding <string> The encoding used for all stdio inputs and outputs. Default: 'buffer'.

    • shell <boolean> | <string> 如果是 true,则在 shell 内运行 command。在 Unix 上使用 '/bin/sh',在 Windows 上使用 process.env.ComSpec。可以将不同的 shell 指定为字符串。参见 Shell 要求默认 Windows shell。默认值:false(无壳)。

      shell <boolean> | <string> If true, runs command inside of a shell. Uses '/bin/sh' on Unix, and process.env.ComSpec on Windows. A different shell can be specified as a string. See Shell requirements and Default Windows shell. Default: false (no shell).

    • windowsVerbatimArguments <boolean> 在 Windows 上不为参数加上引号或转义。在 Unix 上被忽略。当指定了 shell 并且是 CMD 时,则自动设置为 true。默认值:false

      windowsVerbatimArguments <boolean> No quoting or escaping of arguments is done on Windows. Ignored on Unix. This is set to true automatically when shell is specified and is CMD. Default: false.

    • windowsHide <boolean> 隐藏通常在 Windows 系统上创建的子进程控制台窗口。默认值:false

      windowsHide <boolean> Hide the subprocess console window that would normally be created on Windows systems. Default: false.

  • 返回:<Object>

    Returns: <Object>

    • pid <number> 子进程的 pid。

      pid <number> Pid of the child process.

    • output <Array> 来自标准输入输出的输出的结果数组。

      output <Array> Array of results from stdio output.

    • stdout <Buffer> | <string> output[1] 的内容。

      stdout <Buffer> | <string> The contents of output[1].

    • stderr <Buffer> | <string> output[2] 的内容。

      stderr <Buffer> | <string> The contents of output[2].

    • status <number> | <null> 子进程的退出码,如果子进程因信号而终止,则为 null

      status <number> | <null> The exit code of the subprocess, or null if the subprocess terminated due to a signal.

    • signal <string> | <null> 用于终止子进程的信号,如果子进程没有因信号而终止,则为 null

      signal <string> | <null> The signal used to kill the subprocess, or null if the subprocess did not terminate due to a signal.

    • error <Error> 如果子进程失败或超时,则为错误对象。

      error <Error> The error object if the child process failed or timed out.

child_process.spawnSync() 方法通常与 child_process.spawn() 相同,只是该函数在子进程完全关闭之前不会返回。当遇到超时并发送 killSignal 时,该方法将在进程完全退出之前不会返回。如果进程截获并处理了 SIGTERM 信号没有退出,父进程会一直等到子进程退出。

The child_process.spawnSync() method is generally identical to child_process.spawn() with the exception that the function will not return until the child process has fully closed. When a timeout has been encountered and killSignal is sent, the method won't return until the process has completely exited. If the process intercepts and handles the SIGTERM signal and doesn't exit, the parent process will wait until the child process has exited.

如果启用了 shell 选项,请勿将未经处理的用户输入传递给此函数。任何包含 shell 元字符的输入都可用于触发任意命令执行。

If the shell option is enabled, do not pass unsanitized user input to this function. Any input containing shell metacharacters may be used to trigger arbitrary command execution.

类:ChildProcess#

Class: ChildProcess

ChildProcess 的实例代表派生的子进程。

Instances of the ChildProcess represent spawned child processes.

ChildProcess 的实例不打算直接创建。相反,使用 child_process.spawn()child_process.exec()child_process.execFile()child_process.fork() 方法来创建 ChildProcess 的实例。

Instances of ChildProcess are not intended to be created directly. Rather, use the child_process.spawn(), child_process.exec(), child_process.execFile(), or child_process.fork() methods to create instances of ChildProcess.

事件:'close'#

Event: 'close'

  • code <number> 如果子进程自己退出,则为退出码。

    code <number> The exit code if the child exited on its own.

  • signal <string> 终止子进程的信号。

    signal <string> The signal by which the child process was terminated.

'close' 事件在进程结束并且子进程的 stdio 流关闭后触发。这与 'exit' 事件不同,因为多个进程可能共享相同的 stdio 流。'close' 事件将始终在 'exit' 已经触发后触发,或者如果子项未能生成则为 'error'

The 'close' event is emitted after a process has ended and the stdio streams of a child process have been closed. This is distinct from the 'exit' event, since multiple processes might share the same stdio streams. The 'close' event will always emit after 'exit' was already emitted, or 'error' if the child failed to spawn.

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

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

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

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

事件:'disconnect'#

Event: 'disconnect'

'disconnect' 事件在调用父进程中的 subprocess.disconnect() 方法或子进程中的 process.disconnect() 方法后触发。断开连接后无法再发送或接收消息,subprocess.connected 属性为 false

The 'disconnect' event is emitted after calling the subprocess.disconnect() method in parent process or process.disconnect() in child process. After disconnecting it is no longer possible to send or receive messages, and the subprocess.connected property is false.

事件:'error'#

Event: 'error'

'error' 事件在以下情况下触发:

The 'error' event is emitted whenever:

  • 无法生成该进程。

    The process could not be spawned.

  • 无法终止进程。

    The process could not be killed.

  • 向子进程发送消息失败。

    Sending a message to the child process failed.

  • 子进程已通过 signal 选项中止。

    The child process was aborted via the signal option.

发生错误后,'exit' 事件可能会触发,也可能不会触发。同时监听 'exit''error' 事件时,防止意外调用处理程序函数多次。

The 'exit' event may or may not fire after an error has occurred. When listening to both the 'exit' and 'error' events, guard against accidentally invoking handler functions multiple times.

另见 subprocess.kill()subprocess.send()

See also subprocess.kill() and subprocess.send().

事件:'exit'#

Event: 'exit'

  • code <number> 如果子进程自己退出,则为退出码。

    code <number> The exit code if the child exited on its own.

  • signal <string> 终止子进程的信号。

    signal <string> The signal by which the child process was terminated.

'exit' 事件在子进程结束后触发。如果进程退出,则 code 为进程的最终退出码,否则为 null。如果进程因收到信号而终止,则 signal 是信号的字符串名称,否则为 null。两者之一将始终是非 null

The 'exit' event is emitted after the child process ends. If the process exited, code is the final exit code of the process, otherwise null. If the process terminated due to receipt of a signal, signal is the string name of the signal, otherwise null. One of the two will always be non-null.

触发 'exit' 事件时,子进程 stdio 流可能仍处于打开状态。

When the 'exit' event is triggered, child process stdio streams might still be open.

Node.js 为 SIGINTSIGTERM 建立信号处理程序,Node.js 进程不会因为收到这些信号而立即终止。相反,Node.js 将执行一系列清理操作,然后重新触发已处理的信号。

Node.js establishes signal handlers for SIGINT and SIGTERM and Node.js processes will not terminate immediately due to receipt of those signals. Rather, Node.js will perform a sequence of cleanup actions and then will re-raise the handled signal.

请参阅 waitpid(2)

See waitpid(2).

事件:'message'#

Event: 'message'

当子进程使用 process.send() 发送消息时会触发 'message' 事件。

The 'message' event is triggered when a child process uses process.send() to send messages.

消息经过序列化和解析。结果消息可能与最初发送的消息不同。

The message goes through serialization and parsing. The resulting message might not be the same as what is originally sent.

如果在生成子进程时将 serialization 选项设置为 'advanced',则 message 参数可以包含 JSON 无法表示的数据。有关详细信息,请参阅 高级序列化

If the serialization option was set to 'advanced' used when spawning the child process, the message argument can contain data that JSON is not able to represent. See Advanced serialization for more details.

事件:'spawn'#

Event: 'spawn'

一旦子进程成功生成,就会触发 'spawn' 事件。如果子进程没有成功生成,则不会触发 'spawn' 事件,而是触发 'error' 事件。

The 'spawn' event is emitted once the child process has spawned successfully. If the child process does not spawn successfully, the 'spawn' event is not emitted and the 'error' event is emitted instead.

如果触发,则 'spawn' 事件发生在所有其他事件之前,并且发生在通过 stdoutstderr 接收任何数据之前。

If emitted, the 'spawn' event comes before all other events and before any data is received via stdout or stderr.

无论生成的进程中是否发生错误,都会触发 'spawn' 事件。例如,如果 bash some-command 成功生成,则 'spawn' 事件将触发,但 bash 可能无法生成 some-command。此警告在使用 { shell: true } 时也适用。

The 'spawn' event will fire regardless of whether an error occurs within the spawned process. For example, if bash some-command spawns successfully, the 'spawn' event will fire, though bash may fail to spawn some-command. This caveat also applies when using { shell: true }.

subprocess.channel#

  • <Object> 代表子进程的 IPC 通道的管道。

    <Object> A pipe representing the IPC channel to the child process.

subprocess.channel 属性是对子 IPC 通道的引用。如果不存在 IPC 通道,则此属性为 undefined

The subprocess.channel property is a reference to the child's IPC channel. If no IPC channel exists, this property is undefined.

subprocess.channel.ref()#

如果之前调用过 .unref(),此方法使 IPC 通道保持父进程的事件循环运行。

This method makes the IPC channel keep the event loop of the parent process running if .unref() has been called before.

subprocess.channel.unref()#

此方法使 IPC 通道不保持父进程的事件循环运行,并让它在通道打开时完成。

This method makes the IPC channel not keep the event loop of the parent process running, and lets it finish even while the channel is open.

subprocess.connected#

  • <boolean> 调用 subprocess.disconnect() 后设置为 false

    <boolean> Set to false after subprocess.disconnect() is called.

subprocess.connected 属性指示是否仍然可以从子进程发送和接收消息。当 subprocess.connectedfalse 时,将无法再发送或接收消息。

The subprocess.connected property indicates whether it is still possible to send and receive messages from a child process. When subprocess.connected is false, it is no longer possible to send or receive messages.

subprocess.disconnect()#

关闭父子之间的 IPC 通道,允许子级在没有其他连接保持活动状态时优雅地退出。调用此方法后,父进程和子进程中的 subprocess.connectedprocess.connected 属性(分别)将设置为 false,进程之间将不再可能传递消息。

Closes the IPC channel between parent and child, allowing the child to exit gracefully once there are no other connections keeping it alive. After calling this method the subprocess.connected and process.connected properties in both the parent and child (respectively) will be set to false, and it will be no longer possible to pass messages between the processes.

当接收过程中没有消息时,将触发 'disconnect' 事件。这通常会在调用 subprocess.disconnect() 后立即触发。

The 'disconnect' event will be emitted when there are no messages in the process of being received. This will most often be triggered immediately after calling subprocess.disconnect().

当子进程是 Node.js 实例时(例如使用 child_process.fork() 生成),也可以在子进程中调用 process.disconnect() 方法来关闭 IPC 通道。

When the child process is a Node.js instance (e.g. spawned using child_process.fork()), the process.disconnect() method can be invoked within the child process to close the IPC channel as well.

subprocess.exitCode#

subprocess.exitCode 属性表示子进程的退出代码。如果子进程仍在运行,则该字段将为 null

The subprocess.exitCode property indicates the exit code of the child process. If the child process is still running, the field will be null.

subprocess.kill([signal])#

subprocess.kill() 方法向子进程发送信号。如果没有给出参数,进程将被发送 'SIGTERM' 信号。有关可用信号的列表,请参阅 signal(7)。如果 kill(2)成功,该函数返回 true,否则返回 false

The subprocess.kill() method sends a signal to the child process. If no argument is given, the process will be sent the 'SIGTERM' signal. See signal(7) for a list of available signals. This function returns true if kill(2) succeeds, and false otherwise.

const { spawn } = require('node:child_process');
const grep = spawn('grep', ['ssh']);

grep.on('close', (code, signal) => {
  console.log(
    `child process terminated due to receipt of signal ${signal}`);
});

// Send SIGHUP to process.
grep.kill('SIGHUP'); 

如果无法传递信号,ChildProcess 对象可能会触发 'error' 事件。向已经退出的子进程发送信号不是错误,但可能会产生无法预料的后果。具体来说,如果进程标识符 (PID) 已被重新分配给另一个进程,则信号将被传递给该进程,而这可能会产生意外结果。

The ChildProcess object may emit an 'error' event if the signal cannot be delivered. Sending a signal to a child process that has already exited is not an error but may have unforeseen consequences. Specifically, if the process identifier (PID) has been reassigned to another process, the signal will be delivered to that process instead which can have unexpected results.

虽然该函数被称为 kill,但传递给子进程的信号可能不会真正终止该进程。

While the function is called kill, the signal delivered to the child process may not actually terminate the process.

请参阅 kill(2)以供参考。

See kill(2) for reference.

在不存在 POSIX 信号的 Windows 上,signal 参数将被忽略,进程将被强行突然终止(类似于 'SIGKILL')。有关详细信息,请参阅 信号事件

On Windows, where POSIX signals do not exist, the signal argument will be ignored, and the process will be killed forcefully and abruptly (similar to 'SIGKILL'). See Signal Events for more details.

在 Linux 上,子进程的子进程在试图杀死其父进程时不会终止。在 shell 中运行新进程或使用 ChildProcessshell 选项时,很可能会发生这种情况:

On Linux, child processes of child processes will not be terminated when attempting to kill their parent. This is likely to happen when running a new process in a shell or with the use of the shell option of ChildProcess:

'use strict';
const { spawn } = require('node:child_process');

const subprocess = spawn(
  'sh',
  [
    '-c',
    `node -e "setInterval(() => {
      console.log(process.pid, 'is alive')
    }, 500);"`,
  ], {
    stdio: ['inherit', 'inherit', 'inherit'],
  },
);

setTimeout(() => {
  subprocess.kill(); // Does not terminate the Node.js process in the shell.
}, 2000); 

subprocess[Symbol.dispose]()#

稳定性: 1 - 实验性的

Stability: 1 - Experimental

'SIGTERM' 调用 subprocess.kill()

Calls subprocess.kill() with 'SIGTERM'.

subprocess.killed#

  • <boolean> subprocess.kill() 用于成功向子进程发送信号后设置为 true

    <boolean> Set to true after subprocess.kill() is used to successfully send a signal to the child process.

subprocess.killed 属性表示子进程是否成功接收到来自 subprocess.kill() 的信号。killed 属性并不表示子进程已经终止。

The subprocess.killed property indicates whether the child process successfully received a signal from subprocess.kill(). The killed property does not indicate that the child process has been terminated.

subprocess.pid#

返回子进程的进程标识符 (PID)。如果子进程由于错误而未能生成,则值为 undefined 并触发 error

Returns the process identifier (PID) of the child process. If the child process fails to spawn due to errors, then the value is undefined and error is emitted.

const { spawn } = require('node:child_process');
const grep = spawn('grep', ['ssh']);

console.log(`Spawned child pid: ${grep.pid}`);
grep.stdin.end(); 

subprocess.ref()#

在调用 subprocess.unref() 之后调用 subprocess.ref() 将恢复为子进程删除的引用计数,迫使父进程在退出自身之前等待子进程退出。

Calling subprocess.ref() after making a call to subprocess.unref() will restore the removed reference count for the child process, forcing the parent to wait for the child to exit before exiting itself.

const { spawn } = require('node:child_process');

const subprocess = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: 'ignore',
});

subprocess.unref();
subprocess.ref(); 

subprocess.send(message[, sendHandle[, options]][, callback])#

  • message <Object>

  • sendHandle <Handle>

  • options <Object> options 参数(如果存在)是用于参数化某些类型句柄的发送的对象。options 支持以下属性:

    options <Object> The options argument, if present, is an object used to parameterize the sending of certain types of handles. options supports the following properties:

    • keepOpen <boolean> 当传入 net.Socket 实例时可以使用的值。当为 true 时,套接字在发送过程中保持打开状态。默认值:false

      keepOpen <boolean> A value that can be used when passing instances of net.Socket. When true, the socket is kept open in the sending process. Default: false.

  • callback <Function>

  • 返回:<boolean>

    Returns: <boolean>

当父进程和子进程之间已经建立了 IPC 通道时(即使用 child_process.fork() 时),可以使用 subprocess.send() 方法向子进程发送消息。当子进程是 Node.js 实例时,可以通过 'message' 事件接收这些消息。

When an IPC channel has been established between the parent and child ( i.e. when using child_process.fork()), the subprocess.send() method can be used to send messages to the child process. When the child process is a Node.js instance, these messages can be received via the 'message' event.

消息经过序列化和解析。结果消息可能与最初发送的消息不同。

The message goes through serialization and parsing. The resulting message might not be the same as what is originally sent.

例如,在父脚本中:

For example, in the parent script:

const cp = require('node:child_process');
const n = cp.fork(`${__dirname}/sub.js`);

n.on('message', (m) => {
  console.log('PARENT got message:', m);
});

// Causes the child to print: CHILD got message: { hello: 'world' }
n.send({ hello: 'world' }); 

然后子脚本 'sub.js' 可能如下所示:

And then the child script, 'sub.js' might look like this:

process.on('message', (m) => {
  console.log('CHILD got message:', m);
});

// Causes the parent to print: PARENT got message: { foo: 'bar', baz: null }
process.send({ foo: 'bar', baz: NaN }); 

子 Node.js 进程将拥有自己的 process.send() 方法,允许子进程将消息发送回父进程。

Child Node.js processes will have a process.send() method of their own that allows the child to send messages back to the parent.

发送 {cmd: 'NODE_foo'} 消息时有一种特殊情况。在 cmd 属性中包含 NODE_ 前缀的消息保留供在 Node.js 核心中使用,不会在子项的 'message' 事件中触发。相反,此类消息是使用 'internalMessage' 事件触发的,并由 Node.js 在内部使用。应用应避免使用此类消息或监听 'internalMessage' 事件,因为它可能会更改,恕不另行通知。

There is a special case when sending a {cmd: 'NODE_foo'} message. Messages containing a NODE_ prefix in the cmd property are reserved for use within Node.js core and will not be emitted in the child's 'message' event. Rather, such messages are emitted using the 'internalMessage' event and are consumed internally by Node.js. Applications should avoid using such messages or listening for 'internalMessage' events as it is subject to change without notice.

可以传递给 subprocess.send() 的可选 sendHandle 参数用于将 TCP 服务器或套接字对象传递给子进程。子级将接收该对象作为传递给在 'message' 事件上注册的回调函数的第二个参数。套接字中接收和缓冲的任何数据都不会发送给子级。

The optional sendHandle argument that may be passed to subprocess.send() is for passing a TCP server or socket object to the child process. The child will receive the object as the second argument passed to the callback function registered on the 'message' event. Any data that is received and buffered in the socket will not be sent to the child.

可选的 callback 是一个函数,在消息发送后但在子级可能收到消息之前调用。该函数使用单个参数调用:成功时为 null,失败时为 Error 对象。

The optional callback is a function that is invoked after the message is sent but before the child may have received it. The function is called with a single argument: null on success, or an Error object on failure.

如果没有提供 callback 函数,无法发送消息,ChildProcess 对象将触发 'error' 事件。例如,当子进程已经退出时,可能会发生这种情况。

If no callback function is provided and the message cannot be sent, an 'error' event will be emitted by the ChildProcess object. This can happen, for instance, when the child process has already exited.

如果通道已关闭或未发送消息的积压超过阈值(这使得发送更多消息是不明智的),则 subprocess.send() 将返回 false。否则,该方法返回 truecallback 函数可以用来实现流量控制。

subprocess.send() will return false if the channel has closed or when the backlog of unsent messages exceeds a threshold that makes it unwise to send more. Otherwise, the method returns true. The callback function can be used to implement flow control.

示例:发送服务器对象#

Example: sending a server object

例如,sendHandle 参数可用于将 TCP 服务器对象的句柄传递给子进程,如下例所示:

The sendHandle argument can be used, for instance, to pass the handle of a TCP server object to the child process as illustrated in the example below:

const subprocess = require('node:child_process').fork('subprocess.js');

// Open up the server object and send the handle.
const server = require('node:net').createServer();
server.on('connection', (socket) => {
  socket.end('handled by parent');
});
server.listen(1337, () => {
  subprocess.send('server', server);
}); 

然后子级将收到服务器对象:

The child would then receive the server object as:

process.on('message', (m, server) => {
  if (m === 'server') {
    server.on('connection', (socket) => {
      socket.end('handled by child');
    });
  }
}); 

一旦服务器现在在父子之间共享,一些连接可以由父处理,一些连接由子处理。

Once the server is now shared between the parent and child, some connections can be handled by the parent and some by the child.

虽然上面的示例使用了使用 node:net 模块创建的服务器,但 node:dgram 模块服务器使用完全相同的工作流程,除了监听 'message' 事件而不是 'connection' 以及使用 server.bind() 而不是 server.listen()。然而,这仅在 Unix 平台上受支持。

While the example above uses a server created using the node:net module, node:dgram module servers use exactly the same workflow with the exceptions of listening on a 'message' event instead of 'connection' and using server.bind() instead of server.listen(). This is, however, only supported on Unix platforms.

示例:发送套接字对象#

Example: sending a socket object

同样,sendHandler 参数可用于将套接字句柄传递给子进程。下面的示例生成两个子节点,每个子节点处理具有 "normal" 或 "special" 优先级的连接:

Similarly, the sendHandler argument can be used to pass the handle of a socket to the child process. The example below spawns two children that each handle connections with "normal" or "special" priority:

const { fork } = require('node:child_process');
const normal = fork('subprocess.js', ['normal']);
const special = fork('subprocess.js', ['special']);

// Open up the server and send sockets to child. Use pauseOnConnect to prevent
// the sockets from being read before they are sent to the child process.
const server = require('node:net').createServer({ pauseOnConnect: true });
server.on('connection', (socket) => {

  // If this is special priority...
  if (socket.remoteAddress === '74.125.127.100') {
    special.send('socket', socket);
    return;
  }
  // This is normal priority.
  normal.send('socket', socket);
});
server.listen(1337); 

subprocess.js 将接收套接字句柄作为传递给事件回调函数的第二个参数:

The subprocess.js would receive the socket handle as the second argument passed to the event callback function:

process.on('message', (m, socket) => {
  if (m === 'socket') {
    if (socket) {
      // Check that the client socket exists.
      // It is possible for the socket to be closed between the time it is
      // sent and the time it is received in the child process.
      socket.end(`Request handled with ${process.argv[2]} priority`);
    }
  }
}); 

不要在已传递给子进程的套接字上使用 .maxConnections。父级无法跟踪套接字何时被销毁。

Do not use .maxConnections on a socket that has been passed to a subprocess. The parent cannot track when the socket is destroyed.

子进程中的任何 'message' 处理程序都应验证 socket 是否存在,因为在将连接发送给子进程期间连接可能已关闭。

Any 'message' handlers in the subprocess should verify that socket exists, as the connection may have been closed during the time it takes to send the connection to the child.

subprocess.signalCode#

subprocess.signalCode 属性表示子进程接收到的信号(如果有),否则为 null

The subprocess.signalCode property indicates the signal received by the child process if any, else null.

subprocess.spawnargs#

subprocess.spawnargs 属性表示启动子进程时使用的命令行参数的完整列表。

The subprocess.spawnargs property represents the full list of command-line arguments the child process was launched with.

subprocess.spawnfile#

subprocess.spawnfile 属性表示启动的子进程的可执行文件名。

The subprocess.spawnfile property indicates the executable file name of the child process that is launched.

对于 child_process.fork(),其值将等于 process.execPath。对于 child_process.spawn(),它的值将是可执行文件的名称。对于 child_process.exec(),其值将是启动子进程的 shell 的名称。

For child_process.fork(), its value will be equal to process.execPath. For child_process.spawn(), its value will be the name of the executable file. For child_process.exec(), its value will be the name of the shell in which the child process is launched.

subprocess.stderr#

代表子进程的 stderrReadable Stream

A Readable Stream that represents the child process's stderr.

如果子级生成时 stdio[2] 设置为 'pipe' 以外的任何值,那么这将是 null

If the child was spawned with stdio[2] set to anything other than 'pipe', then this will be null.

subprocess.stderrsubprocess.stdio[2] 的别名。这两个属性将引用相同的值。

subprocess.stderr is an alias for subprocess.stdio[2]. Both properties will refer to the same value.

如果无法成功生成子进程,则 subprocess.stderr 属性可以是 nullundefined

The subprocess.stderr property can be null or undefined if the child process could not be successfully spawned.

subprocess.stdin#

代表子进程的 stdinWritable Stream

A Writable Stream that represents the child process's stdin.

如果子进程等待读取其所有输入,则子进程将不会继续,直到通过 end() 关闭此流。

If a child process waits to read all of its input, the child will not continue until this stream has been closed via end().

如果子级生成时 stdio[0] 设置为 'pipe' 以外的任何值,那么这将是 null

If the child was spawned with stdio[0] set to anything other than 'pipe', then this will be null.

subprocess.stdinsubprocess.stdio[0] 的别名。这两个属性将引用相同的值。

subprocess.stdin is an alias for subprocess.stdio[0]. Both properties will refer to the same value.

如果无法成功生成子进程,则 subprocess.stdin 属性可以是 nullundefined

The subprocess.stdin property can be null or undefined if the child process could not be successfully spawned.

subprocess.stdio#

到子进程的管道稀疏数组,对应于传递给 child_process.spawn()stdio 选项中已设置为值 'pipe' 的位置。subprocess.stdio[0]subprocess.stdio[1]subprocess.stdio[2] 也可分别用作 subprocess.stdinsubprocess.stdoutsubprocess.stderr

A sparse array of pipes to the child process, corresponding with positions in the stdio option passed to child_process.spawn() that have been set to the value 'pipe'. subprocess.stdio[0], subprocess.stdio[1], and subprocess.stdio[2] are also available as subprocess.stdin, subprocess.stdout, and subprocess.stderr, respectively.

在下面的示例中,只有子项的 fd 1 (stdout) 配置为管道,因此只有父项的 subprocess.stdio[1] 是流,数组中的所有其他值都是 null

In the following example, only the child's fd 1 (stdout) is configured as a pipe, so only the parent's subprocess.stdio[1] is a stream, all other values in the array are null.

const assert = require('node:assert');
const fs = require('node:fs');
const child_process = require('node:child_process');

const subprocess = child_process.spawn('ls', {
  stdio: [
    0, // Use parent's stdin for child.
    'pipe', // Pipe child's stdout to parent.
    fs.openSync('err.out', 'w'), // Direct child's stderr to a file.
  ],
});

assert.strictEqual(subprocess.stdio[0], null);
assert.strictEqual(subprocess.stdio[0], subprocess.stdin);

assert(subprocess.stdout);
assert.strictEqual(subprocess.stdio[1], subprocess.stdout);

assert.strictEqual(subprocess.stdio[2], null);
assert.strictEqual(subprocess.stdio[2], subprocess.stderr); 

如果无法成功生成子进程,则 subprocess.stdio 属性可以是 undefined

The subprocess.stdio property can be undefined if the child process could not be successfully spawned.

subprocess.stdout#

代表子进程的 stdoutReadable Stream

A Readable Stream that represents the child process's stdout.

如果子级生成时 stdio[1] 设置为 'pipe' 以外的任何值,那么这将是 null

If the child was spawned with stdio[1] set to anything other than 'pipe', then this will be null.

subprocess.stdoutsubprocess.stdio[1] 的别名。这两个属性将引用相同的值。

subprocess.stdout is an alias for subprocess.stdio[1]. Both properties will refer to the same value.

const { spawn } = require('node:child_process');

const subprocess = spawn('ls');

subprocess.stdout.on('data', (data) => {
  console.log(`Received chunk ${data}`);
}); 

如果无法成功生成子进程,则 subprocess.stdout 属性可以是 nullundefined

The subprocess.stdout property can be null or undefined if the child process could not be successfully spawned.

subprocess.unref()#

默认情况下,父进程将等待分离的子进程退出。为了防止父进程等待给定的 subprocess 退出,则使用 subprocess.unref() 方法。这样做会使父进程的事件循环不将子进程包括在其引用计数中,从而允许父进程独立于子进程退出,除非在子进程和父进程之间建立了 IPC 通道。

By default, the parent will wait for the detached child to exit. To prevent the parent from waiting for a given subprocess to exit, use the subprocess.unref() method. Doing so will cause the parent's event loop to not include the child in its reference count, allowing the parent to exit independently of the child, unless there is an established IPC channel between the child and the parent.

const { spawn } = require('node:child_process');

const subprocess = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: 'ignore',
});

subprocess.unref(); 

maxBuffer 和 Unicode#

maxBuffer and Unicode

maxBuffer 选项指定 stdoutstderr 上允许的最大字节数。如果超过这个值,则子进程终止。这会影响包含多字节字符编码(例如 UTF-8 或 UTF-16)的输出。例如,虽然只有 4 个字符,但 console.log('中文测试') 将向 stdout 发送 13 个 UTF-8 编码字节。

The maxBuffer option specifies the largest number of bytes allowed on stdout or stderr. If this value is exceeded, then the child process is terminated. This impacts output that includes multibyte character encodings such as UTF-8 or UTF-16. For instance, console.log('中文测试') will send 13 UTF-8 encoded bytes to stdout although there are only 4 characters.

Shell 要求#

Shell requirements

shell 应该理解 -c 开关。如果 shell 是 'cmd.exe',它应该理解 /d /s /c 开关并且命令行解析应该是兼容的。

The shell should understand the -c switch. If the shell is 'cmd.exe', it should understand the /d /s /c switches and command-line parsing should be compatible.

默认 Windows shell#

Default Windows shell

虽然 Microsoft 指定 %COMSPEC% 必须包含根环境中的 'cmd.exe' 路径,但子进程并不总是符合相同的要求。因此,在可以生成 shell 的 child_process 函数中,如果 process.env.ComSpec 不可用,则将 'cmd.exe' 用作回退。

Although Microsoft specifies %COMSPEC% must contain the path to 'cmd.exe' in the root environment, child processes are not always subject to the same requirement. Thus, in child_process functions where a shell can be spawned, 'cmd.exe' is used as a fallback if process.env.ComSpec is unavailable.

高级序列化#

Advanced serialization

子进程支持基于 node:v8 模块的序列化 API 的 IPC 序列化机制,基于 HTML 结构化克隆算法。这通常更强大,支持更多的内置 JavaScript 对象类型,如 BigIntMapSetArrayBufferTypedArrayBufferErrorRegExp 等。

Child processes support a serialization mechanism for IPC that is based on the serialization API of the node:v8 module, based on the HTML structured clone algorithm. This is generally more powerful and supports more built-in JavaScript object types, such as BigInt, Map and Set, ArrayBuffer and TypedArray, Buffer, Error, RegExp etc.

但是,这种格式不是 JSON 的完整超集,例如 在此类内置类型的对象上设置的属性将不会通过序列化步骤传递。此外,性能可能不等同于 JSON,具体取决于传递数据的结构。因此,此功能需要在调用 child_process.spawn()child_process.fork() 时通过将 serialization 选项设置为 'advanced' 来选择启用。

However, this format is not a full superset of JSON, and e.g. properties set on objects of such built-in types will not be passed on through the serialization step. Additionally, performance may not be equivalent to that of JSON, depending on the structure of the passed data. Therefore, this feature requires opting in by setting the serialization option to 'advanced' when calling child_process.spawn() or child_process.fork().