nodejs如何从stdin读取键击

ban*_*tic 105 stdin input node.js

是否可以在运行的nodejs脚本中侦听传入的击键?如果我使用process.openStdin()并听取它的'data'事件,那么输入将被缓冲,直到下一个换行符,如下所示:

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

运行这个,我得到:

$ node stdin_test.js
                <-- type '1'
                <-- type '2'
                <-- hit enter
Got chunk: 12
Run Code Online (Sandbox Code Playgroud)

我想要看的是:

$ node stdin_test.js
                <-- type '1' (without hitting enter yet)
 Got chunk: 1
Run Code Online (Sandbox Code Playgroud)

我正在寻找一个与例如红宝石相当的nodejsgetc

这可能吗?

Dan*_*den 118

对于那些因为这个功能被剥离而找到这个答案的人来说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 );
});
Run Code Online (Sandbox Code Playgroud)

非常简单 - 基本上就像process.stdin的文档,setRawMode( true )用于获取原始流,这在文档中更难识别.

  • 谢谢..它很简单,很容易立即实施.. :)正是我想要的. (2认同)
  • 不适用于Node.js 0.8+.您必须导入'keypress'.见Peter Lyons的回答. (2认同)
  • 这个* did *可在0.8下使用,但很有趣,它是如何不断变化的api。 (2认同)
  • 这是正确的答案,其他的已经不起作用了。 (2认同)

Dan*_*anS 58

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

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();
});
Run Code Online (Sandbox Code Playgroud)

  • 别担心,我发现了自己,`process.stdin.resume(); process.stdin.on('data',function(chunk){process.stdout.write('data:'+ chunk);});` (5认同)
  • 这个答案不再有帮助。由于 Node.js API 发生了一些变化。从下面找出正确答案。 (5认同)
  • 将`setRawMode`移动到`openStdin()`下面,因为只有初始化`stdin`才能设置模式. (3认同)
  • 似乎stdin不再发出按键事件,而是发出具有差异参数的数据事件. (3认同)
  • 嘿是`openStdin()`一个已弃用的旧API?(我在2011年之后学会了节点方式......) (2认同)
  • 呃,是的 实际上`stdin.on('keypress',function(chunk,key))`已在最近的版本中被删除.我很确定`openStdin()`已被删除或被弃用.现在,您可以将stdin作为`process.stdin`访问 (2认同)

arv*_*ve0 37

在节点> = 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)
})
Run Code Online (Sandbox Code Playgroud)

请参阅https://github.com/nodejs/node/issues/6626

  • 在7上尝试这个,我得到`process.stdin.setRawMode不是函数`.稍后会尝试深入潜水. (3认同)
  • @MattMolnar该函数仅在TTY时才存在,因此请先检查该函数 (3认同)

Pet*_*ons 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();
Run Code Online (Sandbox Code Playgroud)

  • 这是唯一适合我的.谢谢! (2认同)

bef*_*fzz 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);
Run Code Online (Sandbox Code Playgroud)

如果你运行它并:

  <--type '1'
{1}
  <--type 'a'
{1}[a]
Run Code Online (Sandbox Code Playgroud)

重要代码#1:

require('tty').setRawMode( true );
Run Code Online (Sandbox Code Playgroud)

重要代码#2:

.createInterface( process.stdin, {} );
Run Code Online (Sandbox Code Playgroud)


Jon*_*han 6

这将输出每个按键。使用您喜欢的任何代码更改 console.log 。

process.stdin.setRawMode(true).setEncoding('utf8').resume().on('data',k=>console.log(k))
Run Code Online (Sandbox Code Playgroud)

  • 我的看法:找出用途和操作,是的,这是浪费时间。这真的是我需要的还是不需要的?提前了解可以节省很多时间。 (2认同)