如何使用Unix管理Node.js脚本 管道(在命令行上)?

Lan*_*ard 38 javascript unix pipe command-line-interface node.js

我看到如何使用Node.js流将各种东西连接在一起,但是如何使用Unix将多个脚本连接在一起|,因为其中一些脚本可以是异步的?

$ ./a.js | ./b.js
Run Code Online (Sandbox Code Playgroud)

例:

a.js(chmod 0755)

#!/usr/bin/env node

setTimeout(function(){
  console.log(JSON.stringify({ foo: 'bar' }));
}, 10);
Run Code Online (Sandbox Code Playgroud)

b.js(chmod 0755)

#!/usr/bin/env node

console.log(process.argv);
Run Code Online (Sandbox Code Playgroud)

这是输出:

$ ./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)
Run Code Online (Sandbox Code Playgroud)

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

Aar*_*our 56

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

修复a.js:

process.on("SIGPIPE", process.exit);
Run Code Online (Sandbox Code Playgroud)

如果你添加那一行,那么当没有人再读取它的输出时它就会放弃.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");
});
Run Code Online (Sandbox Code Playgroud)

当然,你不具备做与数据什么.关键是要有一些东西来保持流程的运行; 如果你正在使用它,stdin.on('data', fx)似乎是一件有用的事情.

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

  • 这是最有帮助的.是否有可能以某种方式检查程序是否以"管道"模式使用(或者我们应该称之为什么)?例如,对于CLI程序来说,检查它是否是分叉的(`if(process.send){}`),b)如果没有,检查它是否以"管道模式"调用(如你的例子)如果没有,只需正常输出(假设它是独立调用的).这样CLI程序就可以适应用例.**编辑**:已找到我的答案(http://nodejs.org/api/tty.html) (4认同)