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

时间:2015-01-21 15:25:24

标签: node.js process child-process 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杀死整个进动树。

然而,将两种方法结合在一起时有一些奇怪之处:<​​/ p>

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

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

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

1 个答案:

答案 0 :(得分:1)

我遇到了确切的问题。我从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

  

我们可以使用{detached:true}选项启动子进程,这样这些进程就不会附加到主进程,但会进入一组新的进程。然后在主进程上使用process.kill(-pid)方法,我们可以使用相同的pid组杀死同一组子进程中的所有进程。