2016-11-01 18 views
0
#!/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); 

(StackOverflowのから取られた)上記のコードで失敗は、あなたがechocatlsでそれを養うが、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 

なぜですか?直し方?

答えて

2

それはハッキングのビットだが、これは動作するようです:

var n = require('fs').readSync(0, b, 0, b.length); 

私は(純粋な憶測)だと思うprocess.stdin.fdであること参照時にstdinを非ブロッキングモードにするゲッター(エラーを引き起こしている)。ファイル記述子を直接使用すると、その問題を回避できます。

2

これはstdinからの同期読み取りの問題です。no solution for itおよびwouldn't fixedがあります。process.stdin.fdはパブリックAPIの一部ではないため、決して使用しないでください。より良い、このエラーを回避し、標準入力から読み取るようにpromisifiedバージョンを使用する:

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 
}); 
関連する問題