在 node.js 中生成并终止进程

新手上路,请多包涵

我试图在 javascript 中生成一个进程,并在一段时间后将其终止(出于测试目的)。

最后,这个过程将是一个无限循环,我需要在指定的时间用不同的参数重新启动,所以我认为产生这个过程并杀死它是最好的方法。

我的测试代码是:

 var spawn=require('child_process').spawn
, child=null;

child=spawn('omxplayer', ['test.mp4'], function(){console.log('end');}, {timeout:6000});
console.log('Timeout');
setTimeout(function(){
    console.log('kill');
    child.kill();
}, 1200);

child.stdout.on('data', function(data){
    console.log('stdout:'+data);
});

child.stderr.on('data', function(data){
    console.log('stderr:'+data);
});

child.stdin.on('data', function(data){
    console.log('stdin:'+data);
});

结果是:

 #~$ node test.js
Timeout
kill

但是我还是需要发送ctrl+C来结束程序。我错过了什么?

在 Raspbian 节点 0.10.17 上,omxplayer 是一个二进制文件(视频播放器)。

我试过了:

  • 添加了 chmod +x 到应用程序。
  • 以 root 身份启动。
  • 子进程的暂停标准输入。在 kill 命令中使用所有与终止相关的信号。

我还在应用程序运行时启动了 ps 命令:

 2145    bash
2174    node
2175    omxplayer
2176    omxplayer.bin
2177    ps

所以omxplayer是一个wrapper,谁不在结束的时候杀掉它的子进程,有没有办法得到wrapped进程的pid?

仍然咬灰尘,试过这个:

 spawn('kill', ['-QUIT', '-$(ps opgid= '+child.pid+')']);

我认为这会杀死 omxplayer 的所有孩子,我不知道这样使用 spawn 是错误的还是代码不起作用。

我所做的最后一次编辑是很好的答案,但必须进行一些编辑。

我创建了一个 sh 文件(具有执行权限),如下所示:

 PID=$1
PGID=$(ps opgid= "$PID")
kill -QUIT -"$PGID"

我这样开始:

 execF('kill.sh', [child.pid], function(){
    console.log('killed');
});

而不是 child.kill

我不确定这是否是最好的方法,也不确定代码是否干净,但它确实有效。

我接受任何以更清晰的方式或更好的方式进行回答,而无需执行文件。

原文由 DrakaSAN 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 475
2 个回答

参考 这个讨论

一旦你开始监听 stdin 上的数据,node 将等待 stdin 上的输入,直到它被告知不要这样做。当用户按下 ctrl-d(表示输入结束)或程序调用 stdin.pause() 时,node 停止等待 stdin。

节点程序不会退出,除非它无事可做或等待。发生的事情是,它正在等待 stdin,因此永远不会退出。

尝试将您的 setTimeout 回调更改为

console.log('kill');
child.stdin.pause();
child.kill();

我希望这应该有效。

原文由 robinkc 发布,翻译遵循 CC BY-SA 3.0 许可协议

有一个非常简洁的 npm 包,叫做 tree-kill 可以非常轻松有效地做到这一点。它会终止子进程, 以及 该子进程可能已启动的所有子进程。

 var kill  = require('tree-kill');
const spawn = require('child_process').spawn;

var scriptArgs = ['myScript.sh', 'arg1', 'arg2', 'youGetThePoint'];
var child = spawn('sh', scriptArgs);

// some code to identify when you want to kill the process. Could be
// a button on the client-side??
button.on('someEvent', function(){
    // where the killing happens
    kill(child.pid);
});

原文由 Michael Hall 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题