nodejs stdin에서 키 입력을 읽는 방법


118

실행중인 nodejs 스크립트에서 들어오는 키 입력을 수신 할 수 있습니까? 이벤트를 사용 process.openStdin()하고 수신 'data'하면 다음과 같이 다음 줄 바꿈까지 입력이 버퍼링됩니다.

// stdin_test.js
var stdin = process.openStdin();
stdin.on('data', function(chunk) { console.log("Got chunk: " + chunk); });

이것을 실행하면 다음을 얻습니다.

$ node stdin_test.js
                <-- type '1'
                <-- type '2'
                <-- hit enter
Got chunk: 12

내가보고 싶은 것은 :

$ node stdin_test.js
                <-- type '1' (without hitting enter yet)
 Got chunk: 1

예를 들어 루비에서 와 동등한 nodejs를 찾고 있습니다.getc

이게 가능해?


(이 질문을 더 쉽게 찾을 수 있도록이 주석을 추가합니다. 올바른 단어를 찾는 데 며칠이 걸렸습니다.) : 이것은 줄 바꿈 (새 줄) 문자가 입력되기 전에 문자별로 stdin 문자를 읽는 방법입니다.
어지러운

답변:


62

원시 모드로 전환하면 다음과 같이 할 수 있습니다.

var stdin = process.openStdin(); 
require('tty').setRawMode(true);    

stdin.on('keypress', function (chunk, key) {
  process.stdout.write('Get Chunk: ' + chunk + '\n');
  if (key && key.ctrl && key.name == 'c') process.exit();
});

6
걱정하지 마세요. 저는 제 자신을 찾았습니다process.stdin.resume(); process.stdin.on('data', function (chunk) { process.stdout.write('data: ' + chunk); });
JamesM-SiteGen

3
초기화 된 경우에만 모드를 설정할 수 있으므로을 setRawMode아래로 이동하십시오 . openStdin()stdin
Tower

4
stdin은 더 이상 키 누르기 이벤트를 내 보내지 않고 대신 매개 변수가 다른 데이터 이벤트를 내 보냅니다.
skeggse

2
이봐이다 openStdin()사용되지 않는 오래된 API는? (나는 ... 2,011 후 노드 방법을 배웠)
스티븐 루

3
어, 그래. 사실 stdin.on('keypress',function(chunk,key))최근 버전에서는 제거되었습니다. 그리고 나는 openStdin()제거되었거나 더 이상 사용되지 않는다고 확신 합니다. 이제 stdin에 액세스 할 수 있습니다.process.stdin
Élektra

132

이 기능이에서 제거 되었기 때문에이 답변을 찾는 사람들 tty을 위해 stdin에서 원시 문자 스트림을 얻는 방법은 다음과 같습니다.

var stdin = process.stdin;

// without this, we would only get streams once enter is pressed
stdin.setRawMode( true );

// resume stdin in the parent process (node app won't quit all by itself
// unless an error or process.exit() happens)
stdin.resume();

// i don't want binary, do you?
stdin.setEncoding( 'utf8' );

// on any data into stdin
stdin.on( 'data', function( key ){
  // ctrl-c ( end of text )
  if ( key === '\u0003' ) {
    process.exit();
  }
  // write the key to stdout all normal like
  process.stdout.write( key );
});

매우 간단합니다-기본적으로 process.stdin의 문서와 같지만 문서setRawMode( true ) 에서 식별하기 어려운 원시 스트림을 가져 오는 데 사용 합니다.


2
감사합니다 .. 간단하고 쉽게 구현할 수있었습니다 .. :) 정확히 제가 원했던 것입니다.
Kushal Likhi 2013

2
Node.js 0.8 이상에서는 작동하지 않습니다. 'keypress'를 가져와야합니다. Peter Lyons의 답변을 참조하십시오.
G-Wiz 2013 년

2
0.8로 작업을하지만, 재미는 그러한 끊임없이 변화하는 API를하는 방법.
Dan Heberden 2013 년

작동하려면 키 == '\ u0003'(삼중 등호 대신 double)을
사용해야

1
이것을 쓰기 위해 위, 아래, 왼쪽, 오른쪽 키도 만들 수있는 방법이 있습니까?
Tom R

46

노드> = v6.1.0에서 :

const readline = require('readline');

readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);

process.stdin.on('keypress', (str, key) => {
  console.log(str)
  console.log(key)
})

참조 https://github.com/nodejs/node/issues/6626를


3
7에 이것을 시도하면 process.stdin.setRawMode is not a function. 나중에 조금 더 깊이 들어 가려고 할 것입니다.
Matt Molnar 2016

3
그것은하는 TTY인지 기능 만 존재 @MattMolnar되도록 제 확인
curiousdannii

당신이 외부 단자와 같은 응용 프로그램을 실행하는 데 필요한 @MattMolnar 참조 stackoverflow.com/questions/17309749/...
막심 Shamihulau

29

이 버전은 keypress 모듈을 사용하며 node.js 버전 0.10, 0.8 및 0.6과 iojs 2.3을 지원합니다. 를 실행해야합니다 npm install --save keypress.

var keypress = require('keypress')
  , tty = require('tty');

// make `process.stdin` begin emitting "keypress" events
keypress(process.stdin);

// listen for the "keypress" event
process.stdin.on('keypress', function (ch, key) {
  console.log('got "keypress"', key);
  if (key && key.ctrl && key.name == 'c') {
    process.stdin.pause();
  }
});

if (typeof process.stdin.setRawMode == 'function') {
  process.stdin.setRawMode(true);
} else {
  tty.setRawMode(true);
}
process.stdin.resume();

이것은 노드 v0.10.25에서 작동하지 않지만 process.stdin.setRawMode()대신 사용한다고 말하지만 오류가 발생하고 setRawMode 메소드가 없다고 말합니다. 매우 짜증납니다
Plentybinary

@Plentybinary 실제로 노드 v0.10.25를 실행하고 있지 않다고 생각합니다. 나는 이것을 v0.10.25에 대해 테스트했으며 제대로 작동합니다. 그리고 process.stdin.setRawMode, 존재하는 기능이며, 제대로 작동합니다. 나는 또한 iojs-2.3.1에서 테스트했으며 여전히 거기에서도 작동합니다.
Peter Lyons

FWIW, 이것은 v0.10.40까지 계속해서 잘 작동합니다
John Rix

8

테스트 된 nodejs 0.6.4 ( 0.8.14 버전에서 테스트 실패 ) :

rint = require('readline').createInterface( process.stdin, {} ); 
rint.input.on('keypress',function( char, key) {
    //console.log(key);
    if( key == undefined ) {
        process.stdout.write('{'+char+'}')
    } else {
        if( key.name == 'escape' ) {
            process.exit();
        }
        process.stdout.write('['+key.name+']');
    }

}); 
require('tty').setRawMode(true);
setTimeout(process.exit, 10000);

당신이 그것을 실행하고 :

  <--type '1'
{1}
  <--type 'a'
{1}[a]

중요한 코드 # 1 :

require('tty').setRawMode( true );

중요한 코드 # 2 :

.createInterface( process.stdin, {} );

2
if(Boolean(process.stdout.isTTY)){
  process.stdin.on("readable",function(){
    var chunk = process.stdin.read();
    if(chunk != null)
      doSomethingWithInput(chunk);
  });
  process.stdin.setRawMode(true);
} else {
  console.log("You are not using a tty device...);
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.