Node.js: 杀死 ChildProcess#spawn 的子进程

Node.js: Killing sub processes of ChildProcess#spawn

考虑以下代码:

import {spawn, exec} from 'child_process';

var child = spawn('su',
    [process.env.USER, '-c', 'while (true); do sleep 0.3; echo "tick"; done'], 
    {stdio: ['ignore', 'pipe', 'pipe']}
);

child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);

setTimeout(() => {
    child.kill();
}, 1000);

在这里,我正在尝试 运行 一个特定的脚本,该脚本 运行 是其他一些子进程(在该示例中 su 将产生一个 bash 进程)并且全部关闭。但是,我无法让它像我期望的那样工作。

调用 child.kill() 只会终止 su 的父进程,而不是其子进程 bash

如何才能让它发挥作用 — 调用 exec(`pkill -TERM -P ${child.pid}`) 而不是 child.kill()?据我了解,这将杀死父进程 child.pid.

的整个进程树

然而,当结合两种方法时,它有一些奇怪的地方:

setTimeout(() => {
    child.kill();
    exec(`pkill -TERM -P ${child.pid}`);
}, 1000);`

即使进程已被终止,此代码仍会继续将 tick 写入控制台。

为什么会这样?有人可以解释一下吗?

我正面临着确切的问题。我从 How to kill child processes that spawn their own child processes in Node.js.

找到了解决方案

这是您的代码的工作形式:

const {spawn, exec} = require('child_process');

var child = spawn('./test.sh',
    [], 
    {stdio: ['ignore', 'pipe', 'pipe'], detached: true} // <---- this
);

child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);

setTimeout(() => {
    process.kill(-child.pid); // <---- and this
    // child.kill();
}, 1000);

当我 运行 你的原始代码时,终端阻止我从脚本 运行 su,所以我将测试代码修改为 ./test.sh同样的事情:

(while (true); do sleep 0.3; echo "tick"; done)

所以神奇的行是 detached:trueprocess.kill(-child.pid)

转自original site:

We can start child processes with {detached: true} option so those processes will not be attached to main process but they will go to a new group of processes. Then using process.kill(-pid) method on main process we can kill all processes that are in the same group of a child process with the same pid group.