芽萌丸プログラミング部 @programming
@programming
2020/4/15 12:20 更新✏

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を含む行だけが出力されています。

関連

Node.js

芽萌丸プログラミング部 @programming
芽萌丸プログラミング部@programming
プログラミング関連アカウント。Web標準技術を中心に書いていきます。フロントエンドからサーバサイドまで JavaScript だけで済ませたい人たちの集いです。記事は主に @TanakaSoftwareLab が担当。
オススメ:Zattoyomiで時事ネタチェックの時間節約!