exec ,execFile,spawn 都是运行一个子进程,但是在不同的操作系统上用法和表现有很大差异。
linux/unix
exec运行子进程需要创建一个终端环境(命令行窗口),然后在其中运行命令,execFile则不需要,因此在linux/unix上,execFile的效率更高。
windows
在windows平台上,运行脚本程序(如批处理.bat)必须有一个终端环境(命令行窗口),因此无法使用execFile,只能使用exec和spawn。
exec总是会创建一个新出的终端环境,并在这个终端中运行命令。spawn不需要创建一个新的终端环境,而是直接运行进程并监事进程输出内容。
exec通常用于运行时间较短的命令,spawn通常用于运行长时间运行的命令。exec一次性获取程序输出内容,spawn可以持续获取程序的输出流。
在windows上,exec和spawn都可以借助cmd.exe命令来运行子进程。
// 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}`);
});
或者
// 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) => {
// ...
});
关闭子进程
nodejs帮助文档给的例子很简单:
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');
但是在windows平台上,使用这个方法通常无法关闭,可以采用如下方法:
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)
}
});