0

I've found some questions about writing to child_process standard input, such as Nodejs Child Process: write to stdin from an already initialised process, however, I'm wondering if it is possible to recognize when a process spawned using Node's child_process attempts to read from its standard input and take action on that (perhaps according to what it has written to its standard output up until then).

I see that the stdio streams are implemented using Stream in Node. Stream has an event called data which is for when it is being written into, however, I see no event for detecting the stream is being read from.

Is the way to go here to subclass Stream and override its read method with custom implementation or is there a simpler way?

Tomáš Hübelbauer
  • 9,179
  • 14
  • 63
  • 125

1 Answers1

1

I've played around with Node standard I/O and streams for a bit until I eventually arrived at a solution. You can find it here: https://github.com/TomasHubelbauer/node-stdio

The gist of it is that we need to create a Readable stream and pipe it to the process' standard input. Then we need to listen for the process' standard output and parse it, detect the chunks of interest (prompts to the user) and each time we get one of those, make our Readable output our "reaction" to the prompt to the process' standard input.

Start the process:

const cp = child_process.exec('node test');

Prepare a Readable and pipe it to the process' standard input:

new stream.Readable({ read }).pipe(cp.stdin);

Provide the read implementation which will be called when the process asks for input:

  /** @this {stream.Readable} */
  async function read(/** @type {number} */ size) {
    this.push(await promise + '\n');
  }

Here the promise is used to block until we have an answer to the question the process asked through its standard output. this.push will add the answer to an internal queue of the Readable and eventually it will be sent to the standard input of the process.

An example of how to parse the input for a program prompt, derive an answer from the question, wait for the answer to be provided and then send it to the process is in the linked repository.

Tomáš Hübelbauer
  • 9,179
  • 14
  • 63
  • 125