開啟一個子進程
在Node.js的child_process模塊中,有幾種執(zhí)行外部命令的方法,它們的區(qū)別如下:
-
exec()
這是最簡單的方法,它會直接執(zhí)行一個Shell命令,執(zhí)行結(jié)果會通過回調(diào)函數(shù)返回,適用于需要獲取執(zhí)行結(jié)果的場景。該方法返回一個子進程對象,可以通過此對象來管理子進程的生命周期。
const { exec } = require('child_process');
exec('echo hello world', (err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
console.log(stdout);
});
-
spawn()
這個方法可以啟動一個子進程并與其交互,可以向子進程中寫入數(shù)據(jù),也可以從子進程中讀取數(shù)據(jù)。適用于需要實時交互的場景。
const { spawn } = require('child_process');
const process = spawn('ls', ['-al']);
process.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
process.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
process.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
-
execFile()
這個方法非常適用于直接執(zhí)行可執(zhí)行文件的場景,它不需要通過Shell執(zhí)行,只需要指定可執(zhí)行文件的路徑、參數(shù)、回調(diào)函數(shù)即可。
const { execFile } = require('child_process');
const exePath = 'C:/Program Files/Notepad++/notepad++.exe';
const args = ['test.txt'];
execFile(exePath, args, (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data.toString());
});
-
fork()
這個方法是使用spawn()方法的一種特殊情況,用于在子進程中運行JavaScript文件,并且可以通過IPC機制進行進程間通訊。
// parent.js
const { fork } = require('child_process');
const child = fork('child.js');
child.on('message', (message) => {
console.log(`message from child: ${message}`);
});
child.send('hello from parent');
// child.js
process.on('message', (message) => {
console.log(`message from parent: ${message}`);
});
process.send('hello from child');
以上是四種常用的子進程執(zhí)行命令的方法,選擇哪一種方法要根據(jù)具體業(yè)務(wù)場景和需求進行選擇。
關(guān)閉子進程
當(dāng)你不再需要子進程時,應(yīng)該將其關(guān)閉,以釋放資源和避免意外錯誤。有兩種方法可以關(guān)閉子進程:process.kill() 和 childProcess.kill()
-
process.kill():是一種通用的方法,其可以終止任何一個進程,包括子進程和父進程。你可以使用該方法向子進程發(fā)送可選的信號,例如SIGTERM 和 SIGKILL,以便正常或強制終止子進程。
const { spawn } = require('child_process');
const child = spawn('node', ['childprocess.js']);
setTimeout(() => {
console.log(`Sending SIGTERM to child process ${child.pid}...`);
process.kill(child.pid, 'SIGTERM');
}, 5000);
-
childProces.kill():childProcess.kill() 是一個更專門的方法,其只用于終止與特定 ChildProcess 對象相關(guān)聯(lián)的進程。你可以使用該方法向子進程發(fā)送可選的信號,如 SIGTERM 和 SIGKILL,以便正?;驈娭平K止進程。
const { spawn } = require('child_process');
const child = spawn('node', ['childprocess.js']);
setTimeout(() => {
console.log(`Sending SIGTERM to child process ${child.pid}...`);
child.kill('SIGTERM');
}, 5000);