【问题标题】:Node.js How to use stdin stream to read user input after reading from shell pipeNode.js从shell管道读取后如何使用stdin流读取用户输入
【发布时间】:2016-06-05 00:09:52
【问题描述】:

从 shell 管道收到数据后,我需要通过提示询问用户。但应用程序在从管道读取数据后立即关闭。热到让它等待用户输入?

var readline = require('readline');

var data = '';
process.stdin.setEncoding('utf8');
process.stdin.on('readable', function() {
  var chunk = process.stdin.read();
  if (chunk !== null) {
    data+=chunk;                
  }
}); 

process.stdin.on('end', function() {

  console.log('from pipe: ' + data);

  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });

  rl.question('prompt> ', (answer) => {
    console.log('from prompt: ', answer);
    rl.close();
  });
});

当我运行这个脚本时

$ echo "pipe" | node app.js

打印出来

from pipe: pipe

prompt> 

并立即退出,从不等待提示。

我在 Windows,Node v4.2.1

【问题讨论】:

  • 您在问题中调用rl.close(),所以它关闭了。删除它并仅在实际完成后关闭它。
  • 看起来 Node 线程不等待事件处理程序。
  • @aug rl.close() 实际上没有被调用。代码执行不会进入question回调。
  • @S.D.它确实等待超时:如果我用readline 替换操作setTimeout(function () { console.log('waited'); }, 1000);,它将打印出'等待'
  • 当你使用管道时,这是一个标准输入。读完所有的标准输入后建议你想使用 TTY

标签: node.js stdin prompt node.js-stream


【解决方案1】:

就像@AlexeyTen 在评论中所说,使用ttys 包或使用tty 的类似包,用于需要来自控制台的输入。

var ttys = require('ttys');
const rl = readline.createInterface({
    input: ttys.stdin,
    output: ttys.stdout
});

【讨论】:

    【解决方案2】:

    当 stdin 被 mocha 抑制时,这些解决方案都不适合我。相反,我使用了readline-sync

    function promptToContinue()
    {  
       const readlineSync = require('readline-sync');
    
       if (readlineSync.keyInYN("WARNING this will destroy your file.\n Press [Y/n] to continue> " ))
       {
          // User pressed Y or y
          return;
       } else {
          process.exit(-1);
       }
    }
    

    【讨论】: