本文详细介绍 Node.js 中创建子进程的四种核心方法:exec、execFile、fork 和 spawn。重点解析各方法的适用场景、参数配置及父子进程间的通信机制,特别是 stdio 管道选项(pipe、ignore、inherit)的具体行为与默认设置,帮助开发者根据实际需求选择最优方案。
exec
exec 函数允许在指定的 Shell 环境中执行系统命令。
该函数接受以空格分隔的参数,适用于构建较为复杂的命令字符串。
const { exec } = require('child_process')
exec('cat *.js bad_file | wc -l')exec 方法用于异步创建一个新的子进程,并支持接收回调函数。
exec('cat *.js bad_file | wc -l', (err, stdout, stderr) => {
console.log(stdout)
})传递给回调函数的 stdout 和 stderr 参数将包含子进程的标准输出和标准错误输出内容。
execFile
child_process.execFile(file[, args][, options][, callback])const { execFile } = require('child_process')
execFile('node', ['--version'], (err, stdout, stderr) => {
console.log(stdout)
})execFile 不会直接衍生一个 Shell 进程。
它直接指定可执行文件来创建一个新的进程,从而避免 Shell 解析带来的开销。
fork
child_process.fork(modulePath[, args][, options])fork 方法用于创建一个新的 Node.js 子进程,调用后返回一个子进程对象。
通过 fork 创建的子进程可以与父进程利用内置的 IPC(进程间通信)通道进行数据交换。
衍生出的 Node.js 子进程与其建立的 IPC 通信信道异常处理机制独立于父进程。
每个衍生出的进程都拥有独立的内存空间,并使用各自的 V8 引擎实例。
由于衍生进程需要分配额外的系统资源,因此不建议衍生大量的 Node.js 进程。
在 options 配置对象中,包含以下关键配置项:
silent
该配置用于控制父子进程间 stdin、stdout 和 stderr 的通信行为。
若将其设置为 true,子进程的标准输入和输出将被重定向到父进程中。
parent.js
const { fork } = require('child_process')
const fd = fork('./sub.js')
fd.stdout.on('data', data => console.log(data))
sub.js
console.log('this is sub process')当子进程需要处理 stdin 输入时,可将其直接导入父进程,从而实现与 tty 或 Shell 的交互。
若设置为 false,子进程的标准输入输出将直接继承父进程的设置。
stdio
关于该配置的具体用法详见下文说明。
spawn
child_process.spawn(command[, args][, options])前文提到的 exec、execFile 和 fork 创建新子进程的方法,底层均基于 spawn 方法进行封装。
调用该方法会返回一个子进程对象。
父子进程间的通讯
在使用 fork 和 spawn 创建子进程时,配置选项中包含一个关于 stdio 的字段。
该字段主要用于配置父子进程间的管道连接方式。
默认情况下,子进程的 stdin、stdout 和 stderr 会被重定向到 ChildProcess 对象上对应的 subprocess.stdin、subprocess.stdout 和 subprocess.stderr 流。
这种默认行为等同于将 options.stdio 设置为 ['pipe', 'pipe', 'pipe']。
pipe:等同于 [pipe, pipe, pipe] (默认)ignore:等同于 [ignore, ignore, ignore]inherit:等同于 [process.stdin, process.stdout, process.stderr] 或 [0,1,2]
其中 inherit 表示继承父进程的标准输入输出,即与父进程共享这些流。
const { spawn } = require('child_process');
// 子进程使用父进程的 stdios
spawn('prg', [], { stdio: 'inherit' });
// 衍生的子进程只共享 stderr
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });
// 打开一个额外的 fd=4,用于与程序交互
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] });总结
以上为个人经验总结,希望能给大家一个参考,也希望大家多多支持本站。