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.stdiodetached<boolean> 准备子进程独立于其父进程运行。具体行为取决于平台,请参阅)。options.detacheduid<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对象上的属性公开给父级,为。为 fds 0、1 和 2 创建的管道也可分别用作subprocess.stdio[fd]、subprocess.stdin和subprocess.stdout。目前,这些不是实际的 Unix 管道,因此子进程不能通过它们的说明符文件使用它们,例如subprocess.stderr/dev/fd/2或/dev/stdout。 -
'overlapped':与'pipe'相同,只是在句柄上设置了FILE_FLAG_OVERLAPPED标志。这对于子进程的 stdio 句柄上的重叠 I/O 是必要的。有关详细信息,请参阅docs。这与非 Windows 系统上的'pipe'完全相同。 -
'ipc':创建一个 IPC 通道,用于在父子之间传递消息/文件说明符。最多可以有一个 IPC stdio 文件说明符。设置此选项将启用ChildProcess方法。如果子进程是 Node.js 进程,则 IPC 通道的存在将启用subprocess.send()和process.send()方法,以及子进程内的process.disconnect()和'disconnect'事件。'message'不支持以
以外的任何方式访问 IPC 通道 fd 或将 IPC 通道与不是 Node.js 实例的子进程一起使用。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])。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。
