自習室

こもります

windows で Node.js の child_process.exec を利用する

今回やること

Node.js のプロセスから、引数を渡して hello.exe を実行し、出力を受けてNode.js側で活用する、超シンプルサンプル作成

参考にさせていただきました

Node.jsで外部のコマンドを実行する方法: child_processを使う - memo.yomukaku.net

Windows?

いまこの瞬間触っているコンピュータがWindowsだから「Windowsで」です。実際にNode.jsを使ってサーバプログラムを動かす時は絶対Linuxなので、Windows環境であることはぶっちゃけ蛇足ですが、久しぶりに cl コマンドを使ったのでそれもメモしておきます

環境

コード

app.js

実行されるNode.jsのプログラムは下記。このappもコマンドライン引数を受け取って実行するようにしました。

//app.js
var exec = require('child_process').exec,
  args = process.argv;

var command = "hello";
// "node app" で実行すると、args[0]: "node", args[1]: "app" となるので飛ばす
for( var i = 2; i < args.length; i++ ) {
  command += ( " " + args[i] );
}

console.log( "command: " + command ); // hello hoge fuga これが child_process.exec される

exec(command, function(err, stdout, stderr) {
  if (!err) {
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
  } else {
    console.log(err);
  }
});

hello.cpp

child_process として呼ばれるプログラムは下記。久しぶりにc++を書きました。このプログラムも、コマンドライン引数を受けて、文字列を出力します

#include <iostream>

int main( int argc, char *argv[] ) {
  std::cout << "hello world" << std::endl;
  std::cout << "argc: " << argc << std::endl;
  for( int i = 0; i < argc; i++) {
    std::cout << argv[i] << std::endl;
  }
}

(完全に蛇足の) hello.cpp コンパイル

チュートリアル: コマンド ラインでのネイティブ C++ プログラムのコンパイル

このあたり参照

スタート > Microsoft Visual Studio 2010 Express フォルダ > Visual Studio コマンド プロンプト (2010)

を起動。hello.cpp のあるディレクトリまで移動して、コンパイル

C:\Users\username\address\to\the\code>cl /EHsc hello.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

hello.cpp
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:hello.exe
hello.obj

これでおなじディレクトリに hello.exe が出力されます

実行

node app hoge fuga と実行してみます。

C:\Users\username\address\to\the\code>node app hoge fuga
command: hello hoge fuga
stdout: hello world
argc: 3
hello
hoge
fuga

stderr:

起きていることの確認

  1. "hoge fuga" を引数として node app を実行する
  2. node app 内で先ほどの引数が hello.exe の引数として渡され実行される
  3. それが hello.exe の標準出力として出力される
  4. それを node.js の child_process.exec が返値として受け取る
  5. child_process.exec に登録したコールバック関数がそれを処理する(ここではconsole.log()で書き出すだけ)

最後に

のちのちやりたいのは、サーバで(何かしらの方法で)画像を受け取って、サーバ側のOpenCV的プログラムで画像処理した後、処理結果画像をブラウザで表示する、ようなことです。

今回はその練習としてchild_processに文字列をコマンドライン引数として渡し、文字列を返してもらいました。

画像処理の場合は

  1. 画像受け取ってサーバのローカルの保存する
  2. そのアドレスをコマンドライン引数として child_process.exec() する
  3. 呼び出されたprocess内で画像を処理し、保存し、保存した画像のアドレスを標準出力する
  4. node.js 側でそのアドレスを呼んで、ブラウザに表示したりなんなりする

という流れでしょうか。出来そうな気がします。