如何使用Unix |管道将Node.js脚本连接在一起(在命令行上)

How to pipe Node.js scripts together using the Unix | pipe (on the command line)?

本文关键字:在一起 连接 命令行 脚本 js Unix 何使用 管道 Node      更新时间:2023-09-26

我看到如何使用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.s s (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)

乍一看似乎有很多问题,所以不知道从哪里开始。有办法让它起作用吗?最终目标是能够将./a.jsconsole.log输出用于./b.js。原因是,大多数情况下,这些脚本将一次运行一个,但有时能够将它们连接在一起也不错,所以理想情况下,系统应该能够处理这两种情况。

问题是您的b.js立即结束并关闭其标准in,这会导致a.js出现错误,因为它的标准out被关闭而您没有处理这种可能性。您有两个选项:在a.js中处理stdout关闭或在b.js中接受输入。

修复a.js:
process.on("SIGPIPE", process.exit);

如果你添加了这一行,当没有人再读取它的输出时,它就会放弃。在SIGPIPE上可能有更好的事情要做,这取决于你的程序正在做什么,但关键是要停止console.log的运行。

修复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)似乎是一个有用的事情。

记住,这两种方法中的任何一种都可以防止这个错误。如果您计划在程序之间使用管道,我希望第二种方法最有用。