在NodeJS中exec、execFile、spawn和fork方法的用法和区别是什么?

10 min read

在NodeJS中,exec、execFile、spawn、fork都是可以执行子进程的方法,但它们有以下不同之处。

  1. 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}`);
});
  1. 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);
});

  1. spawn
    spawn(command[, args][, options]) 方法启动并执行一个子进程来执行该命令。此子进程与父进程之间,会建立一个管道。 spawn() 的常规语法如下:
const { spawn } = require('child_process');
const child = spawn('ls', ['-lh', '/usr'], {
  stdio: 'inherit',
  shell: true
});

  1. 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() 的区别主要在于执行方式、参数传递和通信机制不同。需要根据不同的场景选择合适的方法。