Dra*_*SAN 51 javascript 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);
});
Run Code Online (Sandbox Code Playgroud)
结果是:
#~$ node test.js
Timeout
kill
Run Code Online (Sandbox Code Playgroud)
但是我仍然需要发送ctrl + C来结束程序
我错过了什么?
编辑:在Raspbian,节点0.10.17,omxplayer是二进制(视频播放器).
尝试:添加chmod + x到应用程序.以root身份发布.暂停了子进程的标准输入.在kill命令中使用所有与终止相关的信号.
EDIT2:
在应用程序运行时启动ps命令:
2145 bash
2174 node
2175 omxplayer
2176 omxplayer.bin
2177 ps
Run Code Online (Sandbox Code Playgroud)
因此omxplayer do是一个包装器,它在结束时不会结束进程,有没有办法获得包装进程的pid?
EDIT3:
仍然咬着灰尘,试过这个:
spawn('kill', ['-QUIT', '-$(ps opgid= '+child.pid+')']);
Run Code Online (Sandbox Code Playgroud)
我认为会杀死omxplayer的所有孩子,我不知道是否使用了这样的spawn是错的,或者它是否是不起作用的代码.
最后编辑:
我做的最后一次编辑是很好的答案,但不得不被欺骗了一下.
我创建了一个sh文件(执行权限),如下所示:
PID=$1
PGID=$(ps opgid= "$PID")
kill -QUIT -"$PGID"
Run Code Online (Sandbox Code Playgroud)
我从这开始:
execF('kill.sh', [child.pid], function(){
console.log('killed');
});
Run Code Online (Sandbox Code Playgroud)
而不是child.kill.
我不确定这是最好的方法,代码是否干净,但它确实有效.
我将接受任何以更清洁的方式或最好的方式回答,而不必执行文件.
rob*_*nkc 42
请参阅此讨论
一旦开始在stdin上监听数据,节点将等待stdin上的输入,直到它被告知不要.当用户按下ctrl-d(表示输入结束)或程序调用stdin.pause()时,节点将停止等待stdin.
除非没有任何操作或等待,否则节点程序不会退出.发生的事情是,它正在等待stdin,因此永远不会退出.
尝试将setTimeout回调更改为
console.log('kill');
child.stdin.pause();
child.kill();
Run Code Online (Sandbox Code Playgroud)
我希望这应该有效.
Mic*_*all 22
有一个非常简洁的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);
});
Run Code Online (Sandbox Code Playgroud)
小智 8
我和omxplayer有着完全相同的问题,这个博客文章中的解决方案对我有用.
var psTree = require('ps-tree');
var kill = function (pid, signal, callback) {
signal = signal || 'SIGKILL';
callback = callback || function () {};
var killTree = true;
if(killTree) {
psTree(pid, function (err, children) {
[pid].concat(
children.map(function (p) {
return p.PID;
})
).forEach(function (tpid) {
try { process.kill(tpid, signal) }
catch (ex) { }
});
callback();
});
} else {
try { process.kill(pid, signal) }
catch (ex) { }
callback();
}
};
// elsewhere in code
kill(child.pid);
Run Code Online (Sandbox Code Playgroud)