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


  • command <string> 要运行的命令。
  • args <string[]> 字符串参数列表。
  • options <Object>
    • cwd <string> | <URL> 子进程的当前工作目录。
    • env <Object> 环境变量键值对。 默认值: process.env
    • argv0 <string> 显式设置发送给子进程的 argv[0] 的值。 如果未指定,这将设置为 command
    • stdio <Array> | <string> 子进程的标准输入输出配置(参见 options.stdio)。
    • detached <boolean> 准备子进程独立于其父进程运行。 具体行为取决于平台,参见 options.detached
    • uid <number> 设置进程的用户标识(参见 setuid(2))。
    • gid <number> 设置进程的群组标识(参见 setgid(2))。
    • serialization <string> 指定用于在进程之间发送消息的序列化类型。 可能的值为 'json''advanced'。 有关更多详细信息,请参阅高级序列化默认值: 'json'
    • shell <boolean> | <string> 如果是 true,则在 shell 内运行 command。 在 Unix 上使用 '/bin/sh',在 Windows 上使用 process.env.ComSpec。 可以将不同的 shell 指定为字符串。 请参阅 shell 的要求默认的 Windows shell默认值: false (没有 shell)
    • windowsVerbatimArguments <boolean> 在 Windows 上不为参数加上引号或转义。 在 Unix 上被忽略。 当指定了 shell 并且是 CMD 时,则自动设置为 true默认值: false
    • windowsHide <boolean> 隐藏通常在 Windows 系统上创建的子进程控制台窗口。 默认值: false
    • signal <AbortSignal> 允许使用中止信号中止子进程。
    • timeout <number> 允许进程运行的最长时间(以毫秒为单位)。 默认值: undefined
    • killSignal <string> | <integer> 当衍生的进程将被超时或中止信号杀死时要使用的信号值。 默认值: 'SIGTERM'
  • 返回: <ChildProcess>

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

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

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

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

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

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

env 中的 undefined 值将被忽略。

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

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 的方式

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 的示例:

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

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

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

const { spawn } = require('node:child_process');
const controller = new AbortController();
const { signal } = controller;
const grep = spawn('grep', ['ssh'], { signal });
grep.on('error', (err) => {
  // 如果控制器中止,则这将在 err 为 AbortError 的情况下被调用
});
controller.abort(); // 停止子进程
  • command <string> The command to run.
  • args <string[]> List of string arguments.
  • options <Object>
    • cwd <string> | <URL> Current working directory of the child process.
    • env <Object> Environment key-value pairs. Default: process.env.
    • 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> Child's stdio configuration (see options.stdio).
    • detached <boolean> Prepare child to run independently of its parent process. Specific behavior depends on the platform, see options.detached).
    • uid <number> Sets the user identity of the process (see setuid(2)).
    • gid <number> Sets the group identity of the process (see setgid(2)).
    • 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> 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> 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> Hide the subprocess console window that would normally be created on Windows systems. Default: false.
    • signal <AbortSignal> allows aborting the child process using an AbortSignal.
    • timeout <number> In milliseconds the maximum amount of time the process is allowed to run. Default: undefined.
    • killSignal <string> | <integer> The signal value to be used when the spawned process will be killed by timeout or abort signal. Default: 'SIGTERM'.
  • Returns: <ChildProcess>

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.

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

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.

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

undefined values in env will be ignored.

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

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

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.');
});

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

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.

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