0

I am trying to get Node to prompt users for input using the readline module but I have some issues. I put the example from the readline documentation in a file called "prompt.js":

const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
rl.question('What do you think of Node.js? ', (answer) => {
  // TODO: Log the answer in a database
  console.log(`Thank you for your valuable feedback: ${answer}`);
  rl.close();
});

When I execute this command in the Windows console, everything works as expected:

node.exe prompt.js

However, with this command, which is the use-case that interests me, the prompt is displayed, but Node does not wait for user input and terminates immediately:

type prompt.js | node.exe 

Upon investigating, I found that process.stdin.destroyed is true in this second case, before I get to use it.

I tried this example with a few Node versions (12, 14, 15.8.0) and all exhibit this problem. Any idea why piping to node fails? Is this a bug in Node or is there a rational explanation?

Florent Angly
  • 495
  • 5
  • 8
  • You're redirecting stdout from the type command to node's stdin. Node itself will consume the contents of stdin in this case, and by the time readline comes along, it's closed. You would need to have node directly open the console, assuming that's possible. – Anon Coward Feb 12 '21 at 17:05
  • I agree with your analysis. Having dealt with stdin in other programming languages, I find it odd that node.js would close such an essential stream and not provide a way to read from it again... I tried to re-open stdin using the following commands: `fs.createReadStream(null, {fd: process.stdin.fd});` failed with an EOF error and `net.createConnection({fd: process.stdin.fd});` never connected to stdin. – Florent Angly Feb 22 '21 at 15:33
  • The stdin stream that type prompt.js has sent Node has already sent it's EOF. The OS doesn't have a means to re-open a fd. Please reconsider what the first repy said: you are piping stdin to Node to interpret, so there is no stdin available for you to type on (as you seem to expect). No other programming language will do different. (type prompt.js; cat -) | node will keep the stream open but still don't do what you expect- it'll interpret what you type, not prompt. – rektide Jun 29 '21 at 16:53
  • You got me curious, so I tested in Perl and I could not achieve the desired outcome... However, Perl has some workarounds for this use-case. See https://stackoverflow.com/questions/9484431/can-i-prompt-for-user-input-after-reading-piped-input-on-stdin-in-perl – Florent Angly Jun 30 '21 at 18:55

0 Answers0