2016-11-01 4 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); 

(유래에서 촬영) 위의 코드에 실패하면 echo, cat, ls로 공급하지만, curl 출력 실패하는 경우 잘 작동합니다.STDIN 읽기 일부 입력

$ 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을 non-blocking 모드로 설정하는 getter입니다 (이는 오류의 원인이됩니다). 파일 설명자를 직접 사용하면 문제를 해결할 수 있습니다.

2

stdin에서 동기 읽기 문제가 있으며 no solution for itwouldn'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 
});