58

Node.js ストリームを使用して何かを一緒にパイプする方法はわかりました|が、これらのスクリプトの一部が非同期になる可能性がある場合、Unix を使用して複数のスクリプトを一緒にパイプするにはどうすればよいでしょうか?

$ ./a.js | ./b.js

例:

a.js (chmod 0755)

#!/usr/bin/env node

setTimeout(function(){
  console.log(JSON.stringify({ foo: 'bar' }));
}, 10);

b.js (chmod 0755)

#!/usr/bin/env node

console.log(process.argv);

これは出力です:

$ ./a.js | ./b.js
[ 'node', '/Users/viatropos/tests/b.js' ]

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: write EPIPE
    at errnoException (net.js:883:11)
    at Object.afterWrite (net.js:700:19)

一見すると、うまくいかないことがたくさんあるように見えるので、どこから始めればよいかわかりません。これを機能させる方法はありますか?最終的な目標は、console.logからの出力を取得し./a.jsて で使用できるようにすることです./b.js。その理由は、ほとんどの場合、これらのスクリプトは一度に 1 つずつ実行されますが、それらを一緒にパイプできると便利な場合もあるため、システムが両方のケースを処理できることが理想的です。

4

1 に答える 1

75

問題は、標準出力が遮断され、その可能性を処理しなかったため、標準b.js入力がすぐに終了して閉じ、エラーが発生することです。a.js2 つのオプションがあります: stdout のクローズを処理するa.jsか、 で入力を受け入れますb.js

固定a.js:

process.on("SIGPIPE", process.exit);

その行を追加すると、出力を読んでいる人がいなくなったときにあきらめます。あなたのプログラムが何をしているかによっては、おそらく SIGPIPE で行うべきより良いことがありますが、重要なのはconsole.loging を止めることです。

固定b.js:

#!/usr/bin/env node

var stdin = process.openStdin();

var data = "";

stdin.on('data', function(chunk) {
  data += chunk;
});

stdin.on('end', function() {
  console.log("DATA:\n" + data + "\nEND DATA");
});

もちろん、そのデータに対して何もする必要はありません。重要なのは、プロセスを実行し続ける何かを用意することです。配管している場合はstdin.on('data', fx)、便利なことのようです。

これらのいずれかがそのエラーを防ぐことを忘れないでください。プログラム間のパイプを計画している場合は、2 番目の方法が最も役立つと思います。

于 2013-05-03T04:56:26.437 に答える