nodejs如何从stdin读取击键

发布于 2024-10-17 15:51:19 字数 733 浏览 2 评论 0原文

是否可以在正在运行的 Node.js 脚本中侦听传入的击键? 如果我使用 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

我正在寻找一个相当于 getc in ruby​​

这可能吗?

Is it possible to listen for incoming keystrokes in a running nodejs script?
If I use process.openStdin() and listen to its 'data' event then the input is buffered until the next newline, like so:

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

Running this, I get:

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

What I'd like is to see:

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

I'm looking for a nodejs equivalent to, e.g., getc in ruby

Is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

彻夜缠绵 2024-10-24 15:51:19

对于那些因为此功能已从 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 ) 来获取原始流,这在文档中很难识别。

For those finding this answer since this capability was stripped from tty, here's how to get a raw character stream from 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 );
});

pretty simple - basically just like process.stdin's documentation but using setRawMode( true ) to get a raw stream, which is harder to identify in the documentation.

苍暮颜 2024-10-24 15:51:19

在节点 >= 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

In node >= 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)
})

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

慕巷 2024-10-24 15:51:19

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

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

You can achieve it this way, if you switch to raw mode:

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();
});
不一样的天空 2024-10-24 15:51:19

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

This version uses the keypress module and supports node.js version 0.10, 0.8 and 0.6 as well as iojs 2.3. Be sure to run 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();
夏末 2024-10-24 15:51:19

使用 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, {} );

With nodejs 0.6.4 tested (Test failed in 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);

if you run it and:

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

Important code #1:

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

Important code #2:

.createInterface( process.stdin, {} );
菊凝晚露 2024-10-24 15:51:19

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

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

This will output each keypress. Change console.log with whatever code you like.

process.stdin.setRawMode(true).setEncoding('utf8').resume().on('data',k=>console.log(k))
小…红帽 2024-10-24 15:51:19

根据 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)

Based on Dan Heberden's answer, here's an async function -

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

Use like so -

console.log("Press a key...")
const key = await getKeypress()
console.log(key)
一生独一 2024-10-24 15:51:19
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...");
}
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...");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文