Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send input to child process created with spawn? nodejs

Tags:

node.js

I'm running Windows 10, and I have a program, let's call it program, that can be run from the command line. When run, it responds to commands the user enters. The user enters a command, presses the return key, and the program prints a response. I did not make this program and do not have the source, so I cannot modify it.

I want to run this program from within Node.js, and have my Node.js program act as the user, sending it commands and getting the responses. I spawn my program like this:

var spawn = require('child_process').spawn;
var child = spawn('program');

child.stdout.on('data', function(data) {
    console.log(`stdout: ${data}`);
});

Then I attempt to send it a command, for example, help.

child.stdin.write("help\n");

And nothing happens. If I manually run the program, type help, and press the return key, I get output. I want Node.js to run the program, send it input, and receive the output exactly as a human user would. I assumed that stdin.write() would send the program a command as if the user typed it in the console. However, as the program does not respond, I assume this is not the case. How can I send the program input?

I've seen many similar questions, but unfortunately the solutions their authors report as "working" did not work for me.

  • Sending input data to child process in node.js

    I've seen this question and answer and tried everything in it with no success. I've tried ending the command with \r\n instead of \n. I've also tried adding the line child.stdin.end() after writing. Neither of these worked.

  • How to pass STDIN to node.js child process

    This person, in their self-answer, says that they got theirs to work almost exactly as I'm doing it, but mine does not work.

  • Nodejs Child Process: write to stdin from an already initialised process

    This person, in their self-answer, says they got it to work by writing their input to a file and then piping that file to stdin. This sounds overly complicated to send a simple string.

like image 785
gfrung4 Avatar asked May 29 '17 20:05

gfrung4


People also ask

How does Nodejs handle child process?

Usually, Node. js allows single-threaded, non-blocking performance but running a single thread in a CPU cannot handle increasing workload hence the child_process module can be used to spawn child processes. The child processes communicate with each other using a built-in messaging system.

How do you kill child processes that spawn their own child processes in node JS?

var spawn = require('child_process'). spawn; var child = spawn('my-command', {detached: true}); process. kill(-child. pid);


1 Answers

Here is what worked for me. I have used child_process exec to create a child process. Inside this child process Promise, I am handling the i/o part of the cmd given as parameter. Its' not perfect, but its working.

Sample function call where you dont need any human input.

executeCLI("cat ~/index.html");

Sample function call where you interact with aws cli. Here

executeCLI("aws configure --profile dev")

Code for custom executeCLI function.

var { exec } = require('child_process');
async function executeCLI(cmd) {
  console.log("About to execute this: ", cmd);
  var child = exec(cmd);
  return new Promise((resolve, reject) => {
    child.stdout.on('data', (data) => {
      console.log(`${data}`);
      process.stdin.pipe(child.stdin);
    });

    child.on('close', function (err, data) {
      if (err) {
        console.log("Error executing cmd: ", err);
        reject(err);
      } else {
        //   console.log("data:", data)
        resolve(data);
      }
    });
  });
}
like image 140
Baibhav Vishal Avatar answered Sep 22 '22 03:09

Baibhav Vishal