NodeJSのchild_processモジュール

5401 ワード

記事の目次
  • Child Processモジュール
  • 1.1プロファイル
  • 1.2方法
  • 1.2.1 exec()
  • 1.2.2 execFile()
  • 1.2.3 spawn()
  • 1.2.4 fork()
  • 1.2.5 send()
  • 1 Child Processモジュール
    1.1プロファイルchild_processモジュールは 用です.サブプロセスの実行結果は ( 200KB)に格納され、サブプロセスの実行が終了するまで、メインプロセスは でサブプロセスの実行結果を読み取る.
    1.2方法
    1.2.1 exec()execコマンドを実行するための方法です.パラメータはコマンド文字列です.
    var exec = require('child_process').exec;
    var ls = exec('ls -l', function (error, stdout, stderr) {
      if (error) {
        console.log(error.stack);
        console.log('Error code: ' + error.code);
      }
      console.log('Child Process STDOUT: ' + stdout);
    });
    
    上記のコードのbash方法は、サブプロセスを新規作成するために使用され、次いでexec、実行終了後 である. 方法は最大2つのパラメータを受け入れることができ、第1のパラメータは実行されるexecであり、第2のパラメータはshell であり、関数は3つのパラメータを受け入れる.それぞれ である.標準出力と標準エラーはいずれもストリームオブジェクトですので、dataイベントをモニターすることができます.上のコードも下記のように書くことができます.
    var exec = require('child_process').exec;
    var child = exec('ls -l');
    
    child.stdout.on('data', function(data) {
      console.log('stdout: ' + data);
    });
    child.stderr.on('data', function(data) {
      console.log('stdout: ' + data);
    });
    child.on('close', function(code) {
      console.log('closing code: ' + code);
    });
    
    上のコードはまた、サブプロセス自体が 、 、 イベントであり、コールバック関数を設定することができることを示している.上のコードはもう一つのメリットがあります.closeイベントを傍受した後、リアルタイムで結果を出力できます.そうでなければ、サブプロセスが終了するまで、結果が出力されます.したがって、サブプロセスの実行時間が長い場合、または継続して実行する場合、2番目の書き方がいいです.以下は別の例であり、dataファイルがあると仮定する.
    // child.js
    var exec = require('child_process').exec;
    exec('node -v', function(error, stdout, stderr) {
      console.log('stdout: ' + stdout);
      console.log('stderr: ' + stderr);
      if (error !== null) {
        console.log('exec error: ' + error);
      }
    });
    
    運転後、このファイルの出力結果は以下の通りです.
    $ node child.js
    stdout: v0.11.14
    stderr:
    
    child.js方法は、コマンドを説明するために直接bash(/bin/shプログラム)を呼び出しますので、ユーザが入力したパラメータがあれば、exec方法は安全ではありません.
    var path = ";user input";
    child_process.exec('ls -l ' + path, function (err, data) {
      console.log(data);
    });
    
    上記のコードによると、bash環境ではexecが直接運行されます.ユーザーが悪意のコードを入力すると、セキュリティリスクが発生します.したがって、ユーザ入力がある場合は、exec方法ではなく、execFile方法を使用することが望ましい.
    1.2.2 execFile()ls -l; user input方法は、直接に特定のプログラムを実行し、配列としてパラメータが入ってくるので、bashによって説明されないので、より高いセキュリティを有する.
    var child_process = require('child_process');
    
    var path = ".";
    child_process.execFile('/bin/ls', ['-l', path], function (err, result) {
        console.log(result)
    });
    
    上のコードでは、pathはユーザから入力されたと仮定していますが、セミコロンまたは逆引用符が含まれている場合、lsプログラムはそれらの意味を理解していないため、運行結果が得られず、安全性が向上します.
    1.2.3 spawn()execFileは、特定のコマンドを実行するサブルーチンを作成し、spawn と同様の使い方をしていますが、コールバック関数がなく、execFileを介してのみ実行結果を取得することができます.非同期実行に属し、 の場合に適用される.
    var child_process = require('child_process');
    var path = '.';
    var ls = child_process.spawn('/bin/ls', ['-l', path]);
    ls.stdout.on('data', function (data) {
      console.log('stdout: ' + data);
    });
    ls.stderr.on('data', function (data) {
      console.log('stderr: ' + data);
    });
    ls.on('close', function (code) {
      console.log('child process exited with code ' + code);
    });
    
    方法は、2つのパラメータを受け入れ、1つ目は実行可能ファイル、2つ目はパラメータ配列である.spawnオブジェクトは、サブプロセスを表すオブジェクトに戻る.オブジェクトはspawnインターフェースを展開し、そのdataイベントはサブプロセスの出力結果を傍受することができる.spawnの方法はexecの方法と非常に似ていますが、使用形式は少し違っています.
    child_process.exec(command, [options], callback)
    child_process.spawn(command, [args], [options])
    
    1.2.4 fork()EventEmitter方法は、直接にサブプロセスを作成し、Nodeスクリプトを実行し、fork('./child.js')はforkに相当する.spawn方法と違って、forkは親プロセスと子プロセスの間に通信パイプを作り、プロセス間の通信に使う.
    var n = child_process.fork('./child.js');
    n.on('message', function(m) {
      console.log('PARENT got message:', m);
    });
    n.send({ hello: 'world' });
    
    上記のコードでは、spawn('node', ['./child.js'])はプロセス間通信パイプラインを表すオブジェクトに戻り、このオブジェクトに対してfork を傍受して、サブルーチンからの情報を取得しても良いし、サブルーチンに情報を送信しても良い.child.jsスクリプトの内容は以下の通りです.
    process.on('message', function(m) {
      console.log('CHILD got message:', m);
    });
    process.send({ foo: 'bar' });
    
    上のコードでは、サブプロセスがメッセージイベントを傍受し、親プロセスに情報を送信します.
    1.2.5 send()message を用いて新しいプロセスを生成した後、child_process.fork()を用いて新しいプロセスにメッセージを送信することができる.新しいプロセスでは、child.send(message, [sendHandle])を傍受してメッセージを取得する.次の例はメインプロセスのコードです.
    var cp = require('child_process');
    
    var n = cp.fork(__dirname + '/sub.js');
    
    n.on('message', function(m) {
      console.log('PARENT got message:', m);
    });
    
    n.send({ hello: 'world' });
    
    次はサブプロセスsub.jsコードです.
    process.on('message', function(m) {
      console.log('CHILD got message:', m);
    });
    
    process.send({ foo: 'bar' });