【发布时间】:2013-09-12 17:34:56
【问题描述】:
我正在尝试在 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是一个包装器,它结束时不杀死它的子进程,有什么办法可以得到被包装进程的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。
我不确定这是否是最好的方法,也不确定代码是否干净,但它确实有效。
我会接受任何以更简洁的方式,甚至更好,而无需执行文件的答案。
【问题讨论】:
-
Raspbian 上的树莓派(不确定版本),节点 0.10.2。我会尝试更新节点。
-
也许是有特权的东西。尝试使用 root 访问运行您的节点脚本。
-
已将节点更新到 0.10.17 并尝试以 root 身份运行,但均未正常运行。
-
this 可能是 omx 的问题。尝试更新它。
-
我猜 omxplayer 可执行文件是一个将视频输出到屏幕的进程的包装器,它不会关闭它产生的视频进程。
标签: javascript node.js