web-dev-qa-db-ja.com

nodejs stdinからキーストロークを読み取る方法

実行中の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

例えば、Rubyの getcに相当するnodejsを探しています

これは可能ですか?

105
bantic

Rawモードに切り替えると、次のように実現できます。

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();
});
57
DanS

この機能が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 )を使用して生のストリームを取得します。

118
Dan Heberden

ノード> = 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 を参照してください

35
arve0

このバージョンは 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();
29
Peter Lyons

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, {} );
8
befzz
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...);
}
2
Élektra