nodejs stdin'den tuş vuruşlarını okuma


118

Çalışan bir nodejs betiğinde gelen tuş vuruşlarını dinlemek mümkün müdür? Olayını kullanır process.openStdin()ve dinlersem 'data', giriş sonraki satırsonuna kadar arabelleğe alınır, şöyle ki:

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

Bunu çalıştırıyorum:

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

Görmek istediğim şey:

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

Ruby'ye eşdeğer bir nodejs arıyorum, örneğin, getcRuby'de

Mümkün mü?


(Bu soruyu bulmanın daha kolay olması için bu yorumu eklemek; doğru kelimeleri bulmam birkaç günümü aldı): Bu, satırsonu (yeni satır) karakteri girişte gönderilmeden önce karakter karakter stdin'i nasıl okuyacağımıdır.
baş döndürücü

Yanıtlar:


63

Ham moda geçerseniz bunu şu şekilde başarabilirsiniz:

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
Endişelenme, kendimi buldum,process.stdin.resume(); process.stdin.on('data', function (chunk) { process.stdout.write('data: ' + chunk); });
JamesM-SiteGen

3
Kipi yalnızca başlatıldığında ayarlayabileceğiniz için, ' nin setRawModealtında olacak şekilde hareket ettirin . openStdin()stdin
Tower

4
Görünüşe göre, stdin artık bir tuşa basma olayı yayınlamıyor, bunun yerine farklı parametrelerle bir veri olayı yayıyor.
skeggse

2
Hey, openStdin()kullanımdan kaldırılmış ve eski bir API mi? (Düğümü 2011'den sonra öğrendim ...)
Steven Lu

3
Oh evet. Aslında stdin.on('keypress',function(chunk,key))son sürümlerde kaldırılmıştır. Ve openStdin()ya kaldırıldığından ya da kullanımdan kaldırıldığından oldukça eminim . Şimdi, stdin olarak erişebilirsinizprocess.stdin
Élektra

132

Bu cevabı bu yetenekten çıkarıldığından beri bulanlar için tty, işte stdin'den ham bir karakter akışı nasıl elde edilir:

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

oldukça basit - temelde process.stdin'in dokümantasyonu gibi, ancak dokümantasyondasetRawMode( true ) tanımlanması daha zor olan ham bir akış elde etmek için kullanmak .


2
Teşekkürler .. basit ve hemen uygulanması kolaydı .. :) tam da istediğim gibi.
Kushal Likhi

2
Node.js 0.8+ ile çalışmaz. 'Tuşa basmayı' içe aktarmalısınız. Peter Lyons'un cevabına bakın.
G-Wiz

2
Bu yaptığımız 0.8 ile çalışmalarını, ama eğlenceli böyle bir değişen API var nasıl.
Dan Heberden

Çalışması için anahtar == '\ u0003' (üçlü eşit işareti yerine çift) kullanmalı
WHITECOLOR

1
Bunu yukarı, aşağı, sol, sağ tuşlarına da yazmanın bir yolu var mı?
Tom R

47

Düğümde> = 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)
})

Bkz. Https://github.com/nodejs/node/issues/6626


3
Bunu 7'de deniyorum ve anladım process.stdin.setRawMode is not a function. Daha sonra biraz daha derine dalmaya çalışacak.
Matt Molnar

3
@MattMolnar İşlev yalnızca bir TTY ise mevcuttur, bu nedenle ilk önce bunu kontrol edin
Meraklıdannii

@MattMolnar uygulamanızı harici terminal olarak çalıştırmanız gerekiyor, bkz. Stackoverflow.com/questions/17309749/…
Maksim Shamihulau

29

Bu sürüm, tuş basma modülünü kullanır ve node.js sürüm 0.10, 0.8 ve 0.6 ile iojs 2.3'ü destekler. Koştuğundan emin ol 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();

Bu, v0.10.25 düğümünde çalışmıyor, bunun process.stdin.setRawMode()yerine kullan diyor ama bu hata veriyor ve hiçbir yöntem yok diyor setRawMode, çok can sıkıcı
Plentybinary

@Plentybinary Aslında v0.10.25 düğümünü çalıştırmadığınızdan şüpheleniyorum. Bunu v0.10.25'e göre test ettim ve düzgün çalışıyor. ve process.stdin.setRawModevar, bir işlevdir ve düzgün çalışır. Ayrıca iojs-2.3.1 üzerinde de test ettim ve hala orada çalışıyor.
Peter Lyons

FWIW, bu en azından v0.10.40'a kadar güzel bir şekilde çalışmaya devam ediyor
John Rix

8

Nodejs 0.6.4 test edildiğinde ( Test 0.8.14 sürümünde başarısız oldu ):

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

çalıştırırsan ve:

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

Önemli kod 1:

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

Önemli kod 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...);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.