如何检测Node.js脚本是否通过shellpipe道运行?

我的问题类似于这个: 如何检测我的shell脚本是否通过pipe道运行? 。 不同之处在于我正在使用的shell脚本是用Node.js编写的。

假设我input:

echo "foo bar" | ./test.js 

那么怎样才能在test.js获得"foo bar"test.js呢?

我读过Unix和Node:Pipes和Streams,但似乎只是提供了一个asynchronous解决scheme(除非我错了)。 我正在寻找一个同步解决scheme。 而且,用这种技术,检测脚本是否被pipe道化似乎并不是很直接。

TL; DR我的问题是双重的:

  1. 如何检测Node.js脚本是否通过shellpipe道运行,例如echo "foo bar" | ./test.js echo "foo bar" | ./test.js
  2. 如果是这样,如何读出Node.js中的pipe道值?

pipe道是为了处理像“富吧”这样的小input,而且是巨大的文件。

streamAPI确保您可以开始处理数据,而无需等待巨大的文件完全通过(这对速度和内存更好)。 这样做的方式是给你大量的数据。

没有pipe道的同步API。 如果你真的想在做一些事情之前把整个pipe道input放在手中,你可以使用

注意:仅使用节点> = 0.10.0,因为示例使用了stream2 API

 var data = ''; function withPipe(data) { console.log('content was piped'); console.log(data.trim()); } function withoutPipe() { console.log('no content was piped'); } var self = process.stdin; self.on('readable', function() { var chunk = this.read(); if (chunk === null) { withoutPipe(); } else { data += chunk; } }); self.on('end', function() { withPipe(data); }); 

testing

 echo "foo bar" | node test.js 

 node test.js 

我刚刚发现了一个简单的答案,我的问题的一部分。

要快速同步检测是否将pipe道内容传递给Node.js中的当前脚本,请使用process.stdin.isTTY布尔值:

 $ node -p -e 'process.stdin.isTTY' true $ echo 'foo' | node -p -e 'process.stdin.isTTY' undefined 

所以,在一个脚本中,你可以做这样的事情:

 if (process.stdin.isTTY) { // handle shell arguments } else { // handle piped content (see Jerome's answer) } 

我以前没有find这个的原因是因为我正在查看process的文档,其中isTTY根本没有提到。 相反,它在TTY文档中提到。

如果你需要在bash中用inline –evalstringpipe道化nodejs, cat也可以:

 $ echo "Hello" | node -e "console.log(process.argv[1]+' pipe');" "$(cat)" # "Hello pipe" 

你需要检查stdout (而不是像其他地方build议的stdin )像这样:

 if (process.stdout.isTTY) { // not piped } else { // piped }