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

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

6
心配しないで、私は自分自身を見つけましたprocess.stdin.resume(); process.stdin.on('data', function (chunk) { process.stdout.write('data: ' + chunk); });
JamesM-SiteGen

3
が初期化されている場合にのみモードを設定できるため、setRawModeをの下に移動します。openStdin()stdin
Tower

4
stdinはkeypressイベントを発行しなくなったようですが、代わりに、異なるパラメーターを持つデータイベントを発行します。
skeggse 2012

2
ちょっとopenStdin()廃止予定の古いAPIですか?(2011年の後でノードの方法を学びました...)
Steven Lu

3
ええ、ええ。実際stdin.on('keypress',function(chunk,key))、最近のバージョンでは削除されています。そして、私はopenStdin()削除されたか、廃止されたと確信しています。さて、あなたはとしてSTDINにアクセスすることができますprocess.stdin
エレクトラ

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'をインポートする必要があります。ピーター・ライオンズの答えを見てください。
G-Wiz

2
これ 0.8でも機能しましたが、このAPIが絶えず変化するのは楽しいことです。
Dan Heberden 2013年

キー== '\ u0003'(3つの等号ではなく2つ)を使用して動作させる
WHITECOLOR

1
これを上、下、左、右のキーにも書き込む方法はありますか?
トム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、

3
@MattMolnar関数はTTYの場合にのみ存在するので、最初にそれを確認してください
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()代わりにuseと表示されますが、エラーが表示され、setRawModeメソッドは表示されません。非常に煩わしい
Plentybinary

@Plentybinary実際にはノードv0.10.25を実行していないのではないかと思います。これをv0.10.25に対してテストしましたが、正しく動作します。そしてprocess.stdin.setRawMode、存在している機能であり、正常に動作します。私はiojs-2.3.1でもテストしましたが、それでも同様に機能します。
Peter Lyons 2015年

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.