#!/usr/bin/env node
function stdinReadSync() {
var b = new Buffer(1024);
var data = '';
while (true) {
var n = require('fs').readSync(process.stdin.fd, b, 0, b.length);
if (!n) break;
data += b.toString(null, 0, n);
}
return data;
}
var s = stdinReadSync();
console.log(s.length);
如果您使用echo
,cat
,ls
提供代码,则上述代码(取自Stackoverflow)可以正常工作,但会在输出curl
时失败。
$ echo abc | ./test.js
4
$ ls | ./test.js
1056
$ cat 1.txt | ./test.js
78
$ curl -si wikipedia.org | ./test.js
fs.js:725
var r = binding.read(fd, buffer, offset, length, position);
^
Error: EAGAIN: resource temporarily unavailable, read
at Error (native)
at Object.fs.readSync (fs.js:725:19)
at stdinReadSync (/home/ya/2up/api/stdinrd.js:8:29)
at Object.<anonymous> (/home/ya/2up/api/stdinrd.js:15:9)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:456:32)
at tryModuleLoad (module.js:415:12)
at Function.Module._load (module.js:407:3)
at Function.Module.runMain (module.js:575:10)
(23) Failed writing body
为什么呢?怎么解决?
答案 0 :(得分:2)
这是从stdin同步读取的问题,因为我看到有no solution for it和它wouldn't fixed,因为process.stdin.fd不是公共API的一部分,不应该用于无论如何。最好使用promisified版本来避免这个错误并从stdin读取:
function streamToPromise(stream) {
return new Promise((resolve, reject) => {
let chunks = [];
function onData(chunk) {
chunks.push(chunk);
};
function onEnd() {
unbind();
resolve(Buffer.concat(chunks));
};
function onError(error) {
unbind();
reject(error);
};
function unbind() {
stream.removeListener('data', onData);
stream.removeListener('end', onEnd);
stream.removeListener('error', onError);
}
stream.on('data', onData);
stream.on('end', onEnd);
stream.on('error', onError);
});
}
streamToPromise(process.stdin).then((input) => {
// Process input
});
答案 1 :(得分:2)
这有点像黑客,但这似乎有效:
var n = require('fs').readSync(0, b, 0, b.length);
我认为(纯猜想)process.stdin.fd
是一个getter,当被引用时,会将stdin置于非阻塞模式(导致错误)。直接使用文件描述符时,可以解决这个问题。