読者です 読者をやめる 読者になる 読者になる

Node.jsで同期的にコマンドを実行できるようにする execsyncs を作った。

node.js grunt gulp

Node.jsでshellのコマンドを実行する場合は以下のようにする必要がありました。

var exec = require('child_process').exec,
    child;

//child_process.exec関数を利用する
child = exec('cat *.js bad_file | wc -l',
  // exec関数は非同期関数なのでcallbackを取り、そこでstdout, stderrを取る
  function (error, stdout, stderr) {
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
    if (error !== null) {
      console.log('exec error: ' + error);
    }
});

Node.js の v0.11では同期的にコマンドを実行するexecSyncと呼ばれるメソッドがcoreモジュールから提供される事になっています。

これを使うと、同期的に実行するシーンでは以下のように書くことができます。

var execSync = require('child_process').execSync;

//child_process.execSync関数を利用する
var result = "" + execSync('cat *.js bad_file | wc -l');
console.log(result);

こうやって書きたいんですが、Node.js v0.11 からの新機能なので、2014年の7月時点での安定版であるNode.js v0.10では使えません。

そこで v0.10でも v0.11でもexecSyncを使えるようにするライブラリ、execsyncsを作りました

また、v0.12が出たとしてもすぐに移行できるわけではなく、しばらくv0.10とv0.12の両サポート体制は続くと思うので、同期的にコマンドを実行させたい場合は今からでもこのexecsyncsを使っていても良いかと思います。

使い方

インストールはnpmでサクッと。

$ npm install execsyncs

使い方は簡単で、さっきのchild_processのところをrequire('execsyncs')に変えるだけです。

//execsyncsをrequireする
var execsyncs = require('execsyncs');

var result = "" + execsyncs('cat *.js bad_file | wc -l');
console.log(result);

作ってみて思いましたがv0.10でもv0.11でも使えるし、割りと便利なので、gruntとかgulpみたいなタスクランナー系でも活躍しそうだなと思ってプラグインも作っておきました

スクランナー系

スクランナー使っても簡単なコマンドの即時実行としては使えますが、実行結果のstdoutを拾って結果をどうこうするとかそういう事がしたいのであれば、タスクの中で直接execsyncsを使ってください。

実現方法

基本的にはhecomiさんが作ってくれてたexecsyncをv0.11でもコンパイルできるようにNANで加工して、後はchild_process.execSyncメソッドの有無を調べて有ったらコアモジュール側を利用し、無かったらコンパイルした奴を利用しているだけです。

細かい実現方法に関してはgithubを一読ください


バグとか有ったら気軽に報告してください!!

Enjoy sync programming :) !!