exec, execFile y spawn ejecutan un proceso hijo, pero el uso y el rendimiento son bastante diferentes en diferentes sistemas operativos.

Linux/Unix

Exec necesita crear un entorno de terminal (ventana de línea de comando) para ejecutar un subproceso y luego ejecutar comandos en él, pero execFile no lo necesita, por lo que en Linux/Unix, execFile es más eficiente.

ventanas

En la plataforma Windows, se requiere un entorno de terminal (ventana de línea de comando) para ejecutar un programa de script (como Batch.bat), por lo que no se puede usar execFile, solo se pueden usar exec y spawn.

exec siempre crea un nuevo entorno de terminal y ejecuta el comando en este terminal. spawn no necesita crear un nuevo entorno de terminal, sino que ejecuta directamente el proceso y monitorea el resultado del proceso.

exec se utiliza normalmente para comandos de ejecución corta y spawn se utiliza normalmente para comandos de ejecución prolongada. exec obtiene el contenido de salida del programa una vez y spawn puede obtener continuamente el flujo de salida del programa.

En Windows, tanto exec como spawn pueden usar el comando cmd.exe para ejecutar procesos secundarios.

// On Windows Only...
const { spawn } = require('node:child_process');
const bat = spawn('cmd.exe', ['/c', 'my.bat']);

bat.stdout.on('data', (data) => {
  console.log(data.toString());
});

bat.stderr.on('data', (data) => {
  console.error(data.toString());
});

bat.on('exit', (code) => {
  console.log(`Child exited with code ${code}`);
});

o

// OR...
const { exec, spawn } = require('node:child_process');
exec('my.bat', (err, stdout, stderr) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(stdout);
});

// Script with spaces in the filename:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });
// or:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
  // ...
});

cerrar proceso hijo

El ejemplo dado por la documentación de ayuda de nodejs es muy simple:

const { spawn } = require('node:child_process');
const grep = spawn('grep', ['ssh']);

grep.on('close', (code, signal) => {
  console.log(
    `child process terminated due to receipt of signal ${signal}`);
});

// Send SIGHUP to process.
grep.kill('SIGHUP');

Sin embargo, en la plataforma Windows, este método generalmente no se puede cerrar y se pueden usar los siguientes métodos:

const { spawn } = require('node:child_process');
const grep = spawn('grep', ['ssh']);

grep.on('exit', (code) => {
  console.log(
    `child process terminated with code ${code}`);
});

// kill process. On Windows Only...
let pid = grep.pid;
exec(`taskkill /PID ${pid} /T /F`, (error, stdout, stderr)=>{
	console.log("taskkill stdout: " + stdout)
  console.log("taskkill stderr: " + stderr)
  if(error){
      console.log("error: " + error.message)
  }
 });