nodejs如何从标准输入读取击键

yuvru6vn  于 2023-02-08  发布在  Node.js
关注(0)|答案(8)|浏览(169)

是否可以在运行的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,它相当于ruby中的getc
这可能吗?

nsc4cvqm

nsc4cvqm1#

由于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 )获取原始流,这在文档中很难识别。

qlckcl4x

qlckcl4x2#

如果您切换到原始模式,可以通过以下方式实现:

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

6uxekuva3#

在节点〉= v6.1.0中:

const readline = require('readline');

readline.emitKeypressEvents(process.stdin);

if (process.stdin.setRawMode != null) {
  process.stdin.setRawMode(true);
}

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

参见https://github.com/nodejs/node/issues/6626

wixjitnu

wixjitnu4#

该版本使用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();
vuktfyat

vuktfyat5#

测试了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, {} );
mkshixfv

mkshixfv6#

这将输出每一个按键。用你喜欢的代码修改console.log。

process.stdin.setRawMode(true).setEncoding('utf8').resume().on('data',k=>console.log(k))
8i9zcol2

8i9zcol27#

根据Dan Heberden的答案,这里有一个异步函数-

async function getKeypress() {
  return new Promise(resolve => {
    var stdin = process.stdin
    stdin.setRawMode(true) // so get each keypress
    stdin.resume() // resume stdin in the parent process
    stdin.once('data', onData) // like on but removes listener also
    function onData(buffer) {
      stdin.setRawMode(false)
      resolve(buffer.toString())
    }
  })
}

像这样使用-

console.log("Press a key...")
const key = await getKeypress()
console.log(key)
q3aa0525

q3aa05258#

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

相关问题