如何如果Node.js的脚本,通过壳管运行检测?(How to detect if a Node.j

2019-07-21 20:22发布

我的问题是类似这样的: 如何在我的shell脚本通过管道运行检测? 。 不同的是,我工作的shell脚本是写在Node.js的

比方说,我输入:

echo "foo bar" | ./test.js

然后,我怎么能得到价值"foo bar"test.js

我读过Unix和节点:管道和流 ,但只似乎提供了一个异步解决方案(除非我错了)。 我正在寻找一个解决方案同步。 此外,使用这种技术,它似乎并不非常简单的检测,如果脚本被管道与否。

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

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

Answer 1:

管道是由办理小额输入,比如“富巴”,但也是巨大的文件。

流API可以确保您可以启动,而无需等待通过完全被管道输送大文件处理数据(这是速度和内存更好)。 它这样做的方法是给你的数据块。

有管道没有同步API。 如果你真的想在你的手中做某件事之前整个管道输入,你可以使用

注意:只使用节点> = 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);
});

测试用

echo "foo bar" | node test.js

node test.js


Answer 2:

我只是找到了一个简单的回答我的问题的一部分。

要快速,同步检测,如果通过管道输送的内容被传递到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)
}

之前我没有发现这样做的原因是因为我一直在寻找的文档process ,其中isTTY没有提及的。 相反,它在真实中提到的TTY文件 。



Answer 3:

如果你需要管进入使用bash中内嵌--eval串的NodeJS, cat也工作:

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


Answer 4:

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

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


文章来源: How to detect if a Node.js script is running through a shell pipe?