Node.jsからコマンドを別プロセスとして実行
この記事は最終更新日から1年以上が経過しています。
芽萌丸プログラミング部@programming
投稿日 2019/11/16
更新日 2020/6/11 ✏

Node.jsからコマンドを別プロセスとして実行

Node.jsアプリケーションから別プロセスを実行する方法です。 今回はNode.jsアプリケーションからあるコマンドラインツールを実行してみます。実行されたコマンドラインツールはメインアプリケーションのプロセスから切り離され、別プロセスとして動きます。

目次

サンプルコード

メインアプリケーション

コマンドラインツールを外部プロセスとして実行するロジック:

//
// app.js
// 
const { spawn } = require('child_process');

// 実行したい外部コマンド: (tick.logへ10回ログ出力します)
const commandline = "node cli/tick.js --times=10 --logfile=tick.log";
runCommand(commandline);

/** コマンドを外部プロセスとして実行 */
function runCommand(commandline) {
  console.log("running commandline: %s", commandline);
  const parts = commandline.split(" ");
  const cmd = parts[0];
  const args = parts.splice(1);

  // バックグラウンドで実行:
  // メインプロセスが終了しても外部プロセスとして動作します。
  const child = spawn(cmd, args, {
    stdio: 'ignore', // piping all stdio to /dev/null
    detached: true, // メインプロセスから切り離す設定
    env: process.env, // NODE_ENV を tick.js へ与えるため
  });
  child.unref(); // メインプロセスから切り離す
}

上記のコードは、node cli/tick.js --times=3 --logfile=tick.logというコマンドを外部プロセスとして実行するメインプロセスです。

cli/tick.jsはテキトーなログをファイルへ数回出力するだけの簡単なサンプルnodeアプリケーションです。メインプロセスから実行される外部プロセスです。コードは次の通り:

外部コマンドラインツール

//
// cli/tick.js
// 
// ログをn回出力するだけの簡単なcliツール
// Usage: $ node cli/tick.js --times=3 --logfile=tick.log
// 
const fs = require('fs');
const argv = require('minimist')(process.argv.slice(2));

let { times, logfile } = argv;
if (!times) times = 10;
if (!logfile) logfile = './tick.log';


// 標準出力をログファイルへ出力:
const logstream = fs.createWriteStream(logfile, { flags: 'a' });
console.log = function(d) {
  logstream.write(new Date().toLocaleString() + ': ' + d + '\n');
};

// ティック実行:
let time = 0;
const intervalId = setInterval(() => {
  console.log("tick...");
  time += 1;
  if (time >= times) {
    clearInterval(intervalId);
    console.log("end.");
  }
}, 1000);

実行

メインアプリケーション(app.js)を実行:

## 依存モジュールをインストール:
$ npm install --save minimist
## メインアプリケーションを実行:
$ node app.js
running command: node cli/tick.js --times=10 --logfile=tick.log

ログをチェックしてみます:

$ tail -f ./tick.log
...
2019-11-16 07:41:59: tick...
2019-11-16 07:42:00: tick...
2019-11-16 07:42:01: tick...
2019-11-16 07:42:01: end.

tail コマンドで tick.log を監視してみると、メインアプリケーションのプロセス(app.js)が終了した後も外部プロセス(tick.js)は動き続けたことが分かると思います。

NOTE:普通にメインプロセスから実行するだけ(外部プロセスとして切り離して実行しない)のであれば、Node.jsからLinuxコマンドを実行を参考にしてください。

以上です。


芽萌丸プログラミング部
芽萌丸プログラミング部@programming
プログラミング関連アカウント。Web標準技術を中心に書いていきます。フロントエンドからサーバサイドまで JavaScript だけで済ませたい人たちの集いです。記事は主に @TanakaSoftwareLab が担当。