官方文档:https://nodejs.org/api/child_process.html
nodejs创建子进程主要有4个函数:
spawn、exec、execFile、fork
这四个函数均是异步函数,对应的同步函数为:spawnSync、execSync、execFileSync,其中 fork 没有对应的 forkSync
spawn是其他函数的基础,其他三个函数是在spawn上不同程度的封装,exec调用execFile,而execFile调用spawn,fork调用spawn
因此了解了spawn方法的使用,其他三个类似
spawn
先看一下定义如下:
child_process.spawn(command[, args][, options])
command <string>: 运行的命令
args <string[]>: 运行命令所需的参数数组
options <Object>: 可选项
cwd <string> | <URL>: 子进程的工作目录
env <Object>: 环境变量键值对
argv0 <string>: 显式设置发送给子进程的 argv[0] 的值
stdio <Array> | <string>: 子进程标准输出流配置(详看:https://nodejs.org/api/child_process.html#optionsstdio)
detached <boolean>: 是否独立与主进程
uid <number>: 用户id
gid <number>: 用户组id
shell <boolean> | <string>: 命令是否在shell中运行
signal <AbortSignal>: 允许使用信号量终止子进程
timeout <number>: 子进程允许允许的最大时间
killSignal <string> | <integer>: 超时或被杀死时设置的信号值,默认是'SIGTERM'
Returns: <ChildProcess> 子进程对象
调用一个python脚本示例如下:
const ls = spawn('ls', ['-lh', '/usr']);
// 获取标准输出流
subProcess.stdout.on('data', (data) => {
console.log('标准输出 ----> ', data.toString('utf8'));
})
// 获取标准错误输出流
subProcess.stderr.on('data', data => {
console.log('标准错误输出 ----> ', data.toString('utf8'));
});
// 子进程退出事件
subProcess.on('exit', (code, signal) => {
console.log('子进程已退出,code:' + code + ', signal: ', signal);
});
// 子进程输出流关闭事件
subProcess.on('close', (code, signal) => {
console.log('子进程输出流关闭,code:' + code + ', signal: ',signal);
});
execFile
参数构成:child_process.execFile(file[, args][, options][, callback])
与exec类似,但默认不会启动一个shell去执行命令,即直接创建子进程运行可执行文件,因此比exec稍微更高效
const child = execFile('ls', ['-l'], (error, stdout, stderr) => {
if (error) {
throw error;
}
console.log(stdout);
});
exec
参数构成:child_process.exec(command[, options][, callback])
创建子进程时,会开启一个shell,并在shell里运行命令,缓冲任何生成的输出。
执行的命令和参数直接构成一个字符串,不需要像spawn、execFile那样命令参数分开
简单示例:
exec('ls -lh /usr', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.error(`stderr: ${stderr}`);
});
exec() 内部实际是调用 execFile() 。默认会创建shell并在其中执行命令。这在windows更友好,原因是 windows下,.bat和.cmd文件必须依靠于一个shell才可以允许运行。
fork
child_process.fork(modulePath[, args][, options])
基于spawn,专门用于构建nodejs子进程。
返回的 ChildProcess 对象将有一个额外的内置通信通道,允许消息在父进程和子进程之间来回传递
通常下,生成的 Node.js 子进程独立于父进程,但若在两者之间建立了 IPC 通信通道除外。
每个子进程都有自己的内存,有自己的 V8 实例,由于需要额外的资源分配,因此不建议生成大量子 Node.js 进程
使用自定义 execPath 启动的 Node.js 进程将使用子进程上的环境变量 NODE_CHANNEL_FD 标识的文件描述符 (fd) 与父进程通信
const child = child_process.fork('index.js', [''], {})
child.stdout.on('data', (data) => {
console.log('data ----> ', data)
});