【问题标题】:Node.js: Killing subprocesses of ChildProcess#spawnNode.js:杀死 ChildProcess#spawn 的子进程
【发布时间】:2023-03-22 08:44:01
【问题描述】:

考虑以下代码:

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 写入控制台。

为什么会这样?谁能解释一下?

【问题讨论】:

    标签: node.js process child-process spawn


    【解决方案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 组的子进程的同一组中的所有进程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-08
      • 1970-01-01
      • 2019-04-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多