在NodeJS中,exec、execFile、spawn、fork都是可以执行子进程的方法,但它们有以下不同之处。
- exec
exec(command[, options][, callback])
方法是通过 shell 来执行一个命令,它的参数传递给 shell 进行执行。执行完毕后,shell 给父进程发送一个回调函数。它的常规语法如下:
const { exec } = require('child_process');
exec('ls -l', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.error(`stderr: ${stderr}`);
});
- execFile
execFile(file[, args][, options][, callback])
方法是直接执行一个文件,不通过 shell 执行。它执行时的文件路径和命令行参数需要自己指定。与exec()
相比,execFile()
更加安全。常规语法如下:
const { execFile } = require('child_process');
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
if (error) {
throw error;
}
console.log(stdout);
});
- spawn
spawn(command[, args][, options])
方法启动并执行一个子进程来执行该命令。此子进程与父进程之间,会建立一个管道。spawn()
的常规语法如下:
const { spawn } = require('child_process');
const child = spawn('ls', ['-lh', '/usr'], {
stdio: 'inherit',
shell: true
});
- fork
fork(modulePath[, args][, options])
方法对大多数使用情况而言是 spawn() 的特殊情况,专门用于衍生新的 Node.js 进程。它使用了 child_process.spawn() 方法在一个新的 V8 实例中运行指定的模块,并在父子进程之间建立了一个通信管道。该通信管道允许在父进程和子进程之间发送消息。常规语法如下:
const { fork } = require('child_process');
const child = fork('./child.js');
child.on('message', (message) => {
console.log('The message from child:', message);
});
child.send({ hello: 'world' });
综上所述,exec()
、execFile()
、spawn()
、fork()
的区别主要在于执行方式、参数传递和通信机制不同。需要根据不同的场景选择合适的方法。