child_process.spawn(command[, args][, options])
版本 | 变化 |
---|---|
v16.4.0、v14.18.0 |
|
v15.13.0、v14.18.0 | 添加了超时。 |
v15.11.0、v14.18.0 | 添加了AbortSignal 的 killSignal。 |
v15.5.0、v14.17.0 | 添加了AbortSignal 支持。 |
v13.2.0、v12.16.0 | 现在支持 |
v8.8.0 | 现在支持 |
v6.4.0 | 现在支持 |
v5.7.0 | 现在支持 |
v0.1.90 | 添加于:v0.1.90 |
参数
command
<string> 要运行的命令。args
<string[]> 字符串参数列表。options
<Object>cwd
<string> | <URL> 子进程的当前工作目录。env
<Object> 环境键值对。 默认:process.env
。argv0
<string> 显式设置发送给子进程的argv[0]
的值。如果未指定,这将设置为command
。stdio
<Array> | <string> 孩子的 stdio 配置(参见options.stdio
detached
<boolean> 准备子进程独立于其父进程运行。具体行为取决于平台,请参阅options.detached
uid
<number> 设置进程的用户身份(参见setuid(2)
gid
<number> 设置进程的组标识(参见setgid(2)
serialization
<string> 指定用于在进程之间发送消息的序列化类型。可能的值为'json'
和'advanced'
。有关详细信息,请参阅Advanced serialization。 默认:'json'
。shell
<boolean> | <string> 如果true
,在 shell 内运行command
。在 Unix 上使用'/bin/sh'
,在 Windows 上使用process.env.ComSpec
。可以将不同的 shell 指定为字符串。请参阅 Shell requirements 和 Default Windows shell 。 默认:false
(无 shell )。windowsVerbatimArguments
<boolean> 在 Windows 上不对参数进行引用或转义。在 Unix 上被忽略。当指定shell
并且是 CMD 时,它会自动设置为true
。 默认:false
。windowsHide
<boolean> 隐藏通常在 Windows 系统上创建的子进程控制台窗口。 默认:false
。signal
<AbortSignal> 允许使用 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) => {
// 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
可以让子进程在父进程退出后继续运行。孩子将拥有自己的控制台窗口。一旦为子进程启用,它就不能被禁用。
在非 Windows 平台上,如果 options.detached
设置为 true
,则子进程将成为新进程组和会话的领导者。子进程可以在父进程退出后继续运行,无论它们是否分离。有关详细信息,请参阅
。setsid(2)
默认情况下,父级将等待分离的子级退出。要防止父级等待给定的subprocess
退出,请使用subprocess.unref()
方法。这样做会导致父级的事件循环不将子级包含在其引用计数中,从而允许父级独立于子级退出,除非子级和父级之间已建立 IPC 通道。
当使用detached
选项启动long-running 进程时,进程将不会在父进程退出后继续在后台运行,除非它提供了未连接到父进程的stdio
配置。如果继承父级的stdio
,则子级将保持连接到控制终端。
long-running 进程的示例,通过分离并忽略其父 stdio
文件说明符,以忽略父进程的终止:
const { spawn } = require('node:child_process');
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore'
});
subprocess.unref();
或者,可以将子进程的输出重定向到文件中:
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
#
版本 | 变化 |
---|---|
v15.6.0、v14.18.0 | 添加了 |
v3.3.1 | 值 |
v0.7.10 | 添加于:v0.7.10 |
options.stdio
选项用于配置在父进程和子进程之间建立的管道。默认情况下,孩子的 stdin、stdout 和 stderr 被重定向到
对象上相应的 ChildProcess
、 subprocess.stdin
和 subprocess.stdout
流。这相当于将 subprocess.stderr
options.stdio
设置为等于 ['pipe', 'pipe', 'pipe']
。
为方便起见,options.stdio
可能是以下字符串之一:
'pipe'
:相当于['pipe', 'pipe', 'pipe']
(默认)'overlapped'
:相当于['overlapped', 'overlapped', 'overlapped']
'ignore'
:相当于['ignore', 'ignore', 'ignore']
'inherit'
:等同于['inherit', 'inherit', 'inherit']
或[0, 1, 2]
否则,options.stdio
的值是一个数组,其中每个索引对应于子项中的一个 fd。 fds 0、1 和 2 分别对应于 stdin、stdout 和 stderr。可以指定额外的 fd 来在父子节点之间创建额外的管道。该值为以下之一:
-
'pipe'
:在子进程和父进程之间创建一个管道。管道的父端作为child_process
对象上的属性公开给父级,为subprocess.stdio[fd]
subprocess.stdin
subprocess.stdout
subprocess.stderr
/dev/fd/2
或/dev/stdout
。 -
'overlapped'
:与'pipe'
相同,只是在句柄上设置了FILE_FLAG_OVERLAPPED
标志。这对于子进程的 stdio 句柄上的重叠 I/O 是必要的。有关详细信息,请参阅docs。这与非 Windows 系统上的'pipe'
完全相同。 -
'ipc'
:创建一个 IPC 通道,用于在父子之间传递消息/文件说明符。ChildProcess
subprocess.send()
process.send()
process.disconnect()
'disconnect'
'message'
不支持以
process.send()
-
'ignore'
:指示 Node.js 忽略子级中的 fd。虽然 Node.js 将始终为其生成的进程打开 fds 0、1 和 2,但将 fd 设置为'ignore'
将导致 Node.js 打开/dev/null
并将其附加到子 fd 上。 -
'inherit'
:通过相应的 stdio 流传入/传出父进程。在前三个位置,这分别相当于process.stdin
、process.stdout
和process.stderr
。在任何其他位置,相当于'ignore'
。 -
<Stream> 对象:与子进程共享引用 tty、文件、套接字或管道的可读或可写流。流的底层文件说明符在子进程中复制到与
stdio
数组中的索引对应的 fd。流必须有一个底层说明符(文件流在'open'
事件发生之前没有)。 -
正整数:整数值被解释为当前在父进程中打开的文件说明符。它与子进程共享,类似于如何共享 <Stream> 对象。 Windows 不支持传递套接字。
-
null
,undefined
:使用默认值。对于 stdio fds 0、1 和 2(换句话说,stdin、stdout 和 stderr)创建了一个管道。对于 fd 3 及更高版本,默认值为'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'
事件。这允许子进程正常退出,而进程不会被打开的 IPC 通道保持打开状态。'message'
在Unix-like 操作系统上,
方法在将事件循环与子进程分离之前同步执行内存操作。具有大量内存占用的应用程序可能会发现频繁的 child_process.spawn()
调用是一个瓶颈。有关详细信息,请参阅V8 issue 7381。child_process.spawn()
另请参阅:
和 child_process.exec()
。child_process.fork()
相关用法
- Node.js child_process.fork(modulePath[, args][, options])用法及代码示例
- Node.js child_process.exec(command[, options][, callback])用法及代码示例
- Node.js child_process.execFile(file[, args][, options][, callback])用法及代码示例
- Node.js certificate.verifySpkac(spkac[, encoding])用法及代码示例
- Node.js console.timeEnd()用法及代码示例
- Node.js crypto.randomFill()用法及代码示例
- Node.js crypto.createHmac()用法及代码示例
- Node.js crypto.randomFillSync(buffer[, offset][, size])用法及代码示例
- Node.js console.countReset()用法及代码示例
- Node.js cluster.worker用法及代码示例
- Node.js crypto.constants用法及代码示例
- Node.js crypto.randomInt([min, ]max[, callback])用法及代码示例
- Node.js crypto.publicEncrypt()用法及代码示例
- Node.js console.trace()用法及代码示例
- Node.js console.timeLog()用法及代码示例
- Node.js console.timeStamp()用法及代码示例
- Node.js crypto.publicDecrypt()用法及代码示例
- Node.js console.dir()用法及代码示例
- Node.js crypto.pbkdf2Sync(password, salt, iterations, keylen, digest)用法及代码示例
- Node.js console.log()用法及代码示例
- Node.js crypto.createHash()用法及代码示例
- Node.js crypto.hkdfSync()用法及代码示例
- Node.js crypto.randomFillSync()用法及代码示例
- Node.js crypto.checkPrime()用法及代码示例
- Node.js clienthttp2session.request()用法及代码示例
注:本文由纯净天空筛选整理自nodejs.org大神的英文原创作品 child_process.spawn(command[, args][, options])。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。