我的问题与此类似:How to detect if my shell script is running through a pipe?。不同之处在于我正在处理的shell脚本是用Node.js编写的。
假设我输入:
echo "foo bar" | ./test.js
那么我怎样才能在"foo bar"
中获得值test.js
?
我已阅读Unix and Node: Pipes and Streams,但这似乎只提供了异步解决方案(除非我弄错了)。我正在寻找同步解决方案。此外,使用这种技术,检测脚本是否被管道传输似乎并不是非常简单。
TL; DR我的问题是双重的:
echo "foo bar" | ./test.js
?答案 0 :(得分:44)
我刚刚找到了一个更简单的答案来解答我的问题。
要快速同步检测管道内容是否传递给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
。相反,它在the TTY documentation中提到。
答案 1 :(得分:20)
管道用于处理小输入,如“foo bar”,但也包含大量文件。
流API确保您可以开始处理数据,而无需等待巨大的文件完全通过(这对速度和内存更好)。它的方式是给你数据块。
管道没有同步API。如果你真的想在做某事之前掌握整个管道输入,你可以使用
注意:仅使用node >= 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
答案 2 :(得分:1)
如果您需要在bash中使用内联--eval 字符串管道传输到nodejs,cat
也适用:
$ echo "Hello" | node -e "console.log(process.argv[1]+' pipe');" "$(cat)"
# "Hello pipe"
答案 3 :(得分:1)
您需要检查stdout
(不是stdin
,如同其他地方建议的那样):
if (process.stdout.isTTY) {
// not piped
} else {
// piped
}
答案 4 :(得分:0)
事实证明process.stdin.isTTY
不可靠,因为您可以生成不是TTY的子进程。
我使用here找到了一个更好的解决方案file descriptors。
您可以测试一下这些程序是通过管道输入还是输出:
function pipedIn(cb) {
fs.fstat(0, function(err, stats) {
if (err) {
cb(err)
} else {
cb(null, stats.isFIFO())
}
})
}
function pipedOut(cb) {
fs.fstat(1, function(err, stats) {
if (err) {
cb(err)
} else {
cb(null, stats.isFIFO())
}
})
}
pipedIn((err, x) => console.log("in", x))
pipedOut((err, x) => console.log("out", x))
这里有一些测试证明它有效。
❯❯❯ node pipes.js
in false
out false
❯❯❯ node pipes.js | cat -
in false
out true
❯❯❯ echo 'hello' | node pipes.js | cat -
in true
out true
❯❯❯ echo 'hello' | node pipes.js
in true
out false
❯❯❯ node -p -e "let x = require('child_process').exec(\"node pipes.js\", (err, res) => console.log(res))"
undefined
in false
out false
❯❯❯ node -p -e "let x = require('child_process').exec(\"echo 'hello' | node pipes.js\", (err, res) => console.log(res))"
undefined
in true
out false
❯❯❯ node -p -e "let x = require('child_process').exec(\"echo 'hello' | node pipes.js | cat -\", (err, res) => console.log(res))"
undefined
in true
out true
❯❯❯ node -p -e "let x = require('child_process').exec(\"node pipes.js | cat -\", (err, res) => console.log(res))"
undefined
in false
out true