【问题标题】:How to pipe Node.js scripts together using the Unix | pipe (on the command line)?如何使用 Unix 将 Node.js 脚本连接在一起 |管道(在命令行上)?
【发布时间】:2013-04-27 07:31:48
【问题描述】:

我了解了如何使用 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)

乍一看似乎有很多问题,所以不确定从哪里开始。有没有办法让它工作?最终目标是能够从./a.js 获取console.log 输出并在./b.js 中使用它。原因是,大多数情况下,这些脚本一次运行一个,但有时能够将它们通过管道连接在一起会很好,因此理想情况下,系统应该能够处理这两种情况。

【问题讨论】:

标签: javascript node.js unix pipe command-line-interface


【解决方案1】:

问题是您的b.js 立即结束并关闭其标准输入,这导致a.js 出现错误,因为它的标准输出已关闭而您没有处理这种可能性。您有两个选择:在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) 似乎是一件有用的事情。

请记住,其中任何一个都可以防止该错误。如果您计划在程序之间进行管道传输,我希望第二个最有用。

【讨论】:

  • 这是最有帮助的。是否有可能以某种方式检查程序是否以“管道”模式(或我们应该称之为的任何方式)使用?例如,对于 CLI 程序来说,a) 检查它是否被分叉 (if(process.send) {}),b) 如果不是,检查它是否在“管道模式”中调用(如上面的示例)或 c)如果不是,只是正常输出(假设它是独立调用的)。这样 CLI 程序就可以适应用例。 编辑:已经找到我的答案 (nodejs.org/api/tty.html)
猜你喜欢
  • 1970-01-01
  • 2020-12-21
  • 1970-01-01
  • 1970-01-01
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-29
相关资源
最近更新 更多