Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在node.js中生成并杀死进程_Javascript_Node.js - Fatal编程技术网

Javascript 在node.js中生成并杀死进程

Javascript 在node.js中生成并杀死进程,javascript,node.js,Javascript,Node.js,我试图在javascript中生成一个进程,并在一段时间后将其杀死(出于测试目的) 最后,这个进程将是一个无限循环,我需要在指定的时间用不同的参数重新启动它,所以我认为生成进程并杀死它是最好的方法 我的测试代码是: var spawn=require('child_process').spawn , child=null; child=spawn('omxplayer', ['test.mp4'], function(){console.log('end');}, {timeout:6000}

我试图在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用户身份启动
  • 已暂停子进程的stdin。在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');
});
我是这样开始的:

PID=$1
PGID=$(ps opgid= "$PID")
kill -QUIT -"$PGID"
execF('kill.sh', [child.pid], function(){
    console.log('killed');
});
而不是
child.kill

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


我将接受任何以更干净的方式或更好的方式进行的回答,而不必执行文件。

您已经生成了一个子进程,该子进程已成功终止。但是,主线程仍在执行,这就是为什么必须按Ctrl+C的原因。

请参阅

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

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

尝试将setTimeout回调更改为

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

我希望这能起作用。

最后,我找到了不用脚本的方法:

exec('pkill omxplayer', function(err, stdout, stderr){
    if (stdout){console.log('stdout:'+stdout);}
    if (stderr){console.log('stderr:'+stderr);}
    if (err){throw err;}
    //...
}

我与您在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);

为什么不直接在标准输入管道中发送“q”值呢?它会杀死omxplayer进程。

请尝试从中使用
child\u process.execFile()
方法

child_process.execFile()函数类似于 child_process.exec(),但它不会生成shell。相当地 指定的可执行文件直接作为新进程生成 使其比child_process.exec()稍有效率


在我的例子中,它是有效的。

有一个非常简洁的npm包,名为,它可以非常轻松有效地实现这一点。它将终止子进程,以及该子进程可能已启动的所有子进程

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);
});

必须指定信号:

child.kill('SIGKILL')

如果只是主进程仍在运行,我会很高兴,但子进程显然仍在运行,因为视频仍在播放,直到我在Raspbian上发送ctrl+C.Raspberry Pi(不确定版本),节点0.10.2。我将尝试更新节点。可能是有权限的。尝试使用root访问权限运行节点脚本。将节点更新为0.10.17并尝试以root身份运行,但没有一个运行正常。omx可能存在问题。尝试更新它。我猜omxplayer可执行文件是一个将视频输出到屏幕的进程的包装,它不会关闭它生成的视频进程。我也尝试了这个,并对所有“数据”进行了注释,我仍然需要等待video.Try child.kill('SIGKILL')的结束,看看这是否有效。kill()发送SIGHUP,它只告诉控制终端已关闭或控制进程已关闭。我的假设是SIGKILL肯定会杀死它。试过SIGHUP、SIGTERM和SIGKILL后,kill消息会被打印出来,但视频仍在播放。试过SIGKILL、SIGTERM、SIGABRT、SIGHUP、SIGINT和SIGQUIT后,它们都没有做任何事情,甚至一个接一个地启动。当我尝试生成其他命令(如pidgin)的子代时,代码运行得很好。但它不支持omxplayer吗?嗯,你能解释一下吗?这是omxplayer的自然行为。当您在shell中启动它时,进程正在等待“q”之类的快捷方式,它将关闭程序。这是一个非常干净的解决方案,也适用于其他程序。f、 标准写入(“q\n”);因为需要某种形式的进入。谢谢。这对我有效,似乎是一个很好的选择。这对我有效,而
child.kill()
没有。使用NodeJS v14.15.1,Windows 10I无法对此进行足够的升级-在浪费了5个小时之后,这是唯一适合我在Windows 7上使用的解决方案!这是我唯一可行的解决办法。谢谢