Node.jsでパイプを含んだシェルコマンドを実行
この記事は最終更新日から1年以上が経過しています。
芽萌丸プログラミング部@programming
投稿日 2020/4/15
更新日 2020/4/15 ✏

Node.jsでパイプを含んだシェルコマンドを実行

Node.jsでシェルコマンドを実行する時はchild_processモジュールのspawn関数などを使うと便利です。しかし、spawn関数で|(パイプ)付きのシェルコマンド、例えばcat aaa.txt | grep 'foo'のようなシェルコマンドをそのまま実行しようとしても以下のようなエラーが発生して期待通りには動いてくれません:

stderr: cat: '|': そのようなファイルやディレクトリはありません

|付きのシェルコマンドを実行するためには、spawn関数のオプションにshell: trueをセットする必要があります。

sample.js

const { spawn } = require('child_process');

// 実行したいコマンドライン:
const cmd = "cat aaa.txt | grep 'foo'";

const arr = cmd.trim().split(" ");
const arr0 = arr.shift();

//
// オプションに shell: true をセット
//
const p = spawn(arr0, arr, {
  shell: true, // NOTE: cat aaa.txt | grep "foo" のようなshellのパイプ "|" を処理できるようにする
});
p.on('exit', function(code) {
  console.log("exit:", code);
});
p.on('error', function(err) {
  console.log("error:", err);
});
p.stdout.setEncoding('utf-8');
p.stdout.on('data', function(data) {
  console.log("stdout:", data);
});
p.stderr.setEncoding('utf-8');
p.stderr.on('data', function(data) {
  console.log("stderr:", data);
});

実行例:

## aaa.txtをテキトーに新規作成:
$ echo """
aaa
foo1
bbb
foo2
""" > aaa.txt

## サンプルを実行:
$ node sample.js

stdout: foo1
foo2

exit: 0

sample.js内部でシェルコマンド$ cat aaa.txt | grep fooが実行され、fooを含む行だけが出力されています。

関連


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