web-dev-qa-db-fra.com

nodejs comment lire les frappes sur stdin

Est-il possible d'écouter les frappes entrantes dans un script nodejs en cours d'exécution? Si j'utilise process.openStdin() et que j'écoute ses 'data' événement, l’entrée est mise en mémoire tampon jusqu’à la nouvelle ligne, comme suit:

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

En cours d'exécution, je reçois:

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

Ce que j'aimerais, c'est voir:

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

Je recherche un noeud équivalent à, par exemple, getc en Ruby

Est-ce possible?

105
bantic

Vous pouvez y parvenir de cette manière si vous passez en mode brut:

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

Pour ceux qui trouvent cette réponse depuis que cette capacité a été supprimée de tty, voici comment obtenir un flux de caractères brut à partir de 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 );
});

assez simple - en gros comme la documentation de process.stdin mais en utilisant setRawMode( true ) pour obtenir un flux brut, qui est plus difficile à identifier dans la documentation.

118
Dan Heberden

Dans le noeud> = 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)
})

Voir https://github.com/nodejs/node/issues/6626

35
arve0

Cette version utilise le module touche et prend en charge les versions de node.js 0.10, 0.8 et 0.6 ainsi que iojs 2.3. Assurez-vous de courir 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

Avec nodejs 0.6.4 testé (le test a échoué dans la version 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);

si vous le lancez et:

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

Code important n ° 1:

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

Code important n ° 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