79

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 のすべての子を殺すと思っていましたが、そのようにスポーンを使用することが間違っているのか、それとも動作しないコードなのかはわかりません。

私が行った最後の編集は良い答えでしたが、少し編集する必要がありました.

次のようなshファイル(実行権付き)を作成しました:

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

私は次のように始めます:

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

の代わりにchild.kill

それが最善の方法なのか、コードがきれいなのかはわかりませんが、うまくいきます。

ファイルを実行することなく、よりクリーンな方法で、またはさらに良い方法でそれを行う答えを受け入れます。

4

8 に答える 8

68

このディスカッションを参照してください

標準入力でデータのリッスンを開始すると、ノードは、入力しないように指示されるまで、標準入力での入力を待機します。ユーザーが ctrl-d (入力の終わりを意味する) を押すか、プログラムが stdin.pause() を呼び出すと、ノードは stdin での待機を停止します。

ノードプログラムは、何もすることも待つこともない限り終了しません。何が起こっているのかというと、標準入力を待っているため、終了しません。

setTimeout コールバックを次のように変更してみてください

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

それがうまくいくことを願っています。

于 2013-09-09T09:10:47.103 に答える
1

最後に、スクリプトなしでそれを行う方法を見つけました:

exec('pkill omxplayer', function(err, stdout, stderr){
    if (stdout){console.log('stdout:'+stdout);}
    if (stderr){console.log('stderr:'+stderr);}
    if (err){throw err;}
    //...
}
于 2013-09-10T09:56:23.433 に答える
1

正常に強制終了された子プロセスを生成しました。ただし、メイン スレッドはまだ実行中であるため、Ctrl+C を押す必要があります。

于 2013-09-09T08:58:23.510 に答える
0

ここchild_process.execFile()からメソッドを使用してみてください。

child_process.execFile() 関数は、シェルを生成しない点を除いて、child_process.exec() に似ています。むしろ、指定された実行可能ファイルが新しいプロセスとして直接生成され、child_process.exec() よりもわずかに効率的になります。

私の場合はうまくいきます。

于 2016-02-09T19:53:13.770 に答える