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()
方法使用给定的 command
和 args
中的命令行参数衍生新进程。
如果省略,args
默认为空数组。
如果启用了 shell
选项,则请勿将未经处理的用户输入传递给此函数。
任何包含 shell 元字符的输入都可用于触发任意命令执行。
第三个参数可用于指定其他选项,具有以下默认值:
const defaults = {
cwd: undefined,
env: process.env
};
使用 cwd
指定从中衍生进程的工作目录。
如果没有给定,则默认是继承当前工作目录。
如果给定,但路径不存在,则子进程会触发 ENOENT
错误并立即退出。
当命令不存在时,也会触发 ENOENT
。
使用 env
指定对新进程可见的环境变量,默认为 process.env
。
env
中的 undefined
值将被忽略。
运行 ls -lh /usr
、捕获 stdout
、stderr
和退出码的示例:
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]
不会匹配从父进程传给 spawn
的 argv0
参数。
改为使用 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 ofargv[0]
sent to the child process. This will be set tocommand
if not specified.stdio
<Array> | <string> Child's stdio configuration (seeoptions.stdio
).detached
<boolean> Prepare child to run independently of its parent process. Specific behavior depends on the platform, seeoptions.detached
).uid
<number> Sets the user identity of the process (seesetuid(2)
).gid
<number> Sets the group identity of the process (seesetgid(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> Iftrue
, runscommand
inside of a shell. Uses'/bin/sh'
on Unix, andprocess.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 totrue
automatically whenshell
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