0

I've been trying to capture the output of a child_process for a while now. The following code example is my current attempt.

Code:

// Spawning a shell
var terminal = require('child_process').spawn(`sh`, [], { stdio: [ 'inherit', 'pipe', 'inherit'] });
console.log("Shell spawned!");

terminal.stdout.on('data', (data) => {
  console.log(`Received chunk ${data}`);
});

Output:

Shell spawned!

Expected output:

Shell spawned!

$

When using 'inherit' instead of 'pipe' on the stdout option, I get the expected output. But since I need to capture the output of the process/shell, 'inherit' has no use to me. My question now is, how can I capture the whole output of the process's stdout stream and what is 'inherit' exactly doing? I tried to capture the process.stdout after using 'inherit'- obviously with no luck.

santcleep
  • 3
  • 3
  • Is there a reason you're launching a new shell in the child process? You're essentially forking another process within the child process. – kevintechie Jan 17 '22 at 08:57
  • Did you see [this answer](https://stackoverflow.com/questions/50045741/difference-between-inherit-and-process-pipe-child)? Does it answer your question re inherit vs pipe? – kevintechie Jan 17 '22 at 08:58
  • @kevintechie My reason for this was to check if I could redirect the output if another process in my child_process is spawned. I've tried the argument 'shell: true', which is basically just what im doing here. – santcleep Jan 17 '22 at 09:39

1 Answers1

0

It is not possible to show the prompt from a child process shell because bash (and I assume other shells) don't output the prompt to stdout. See this post for details.

You can simulate it by writing to standard out instead of console.log().

const term = require('child_process')
  .spawn('sh', [], { stdio: [ 'inherit', 'pipe', 'pipe'] });

process.stdout.write('$ ');

term.stdout.on('data', (data) => {
  process.stdout.write(`\n${data}$ `);
});

term.stderr.on('data', (data) => {
  process.stderr.write(`\n${data}$ `);
});
kevintechie
  • 1,441
  • 1
  • 13
  • 15
  • I just found the [node-pty module](https://github.com/microsoft/node-pty) that might give you exactly what you're looking for. – kevintechie Jan 17 '22 at 11:06
  • The post you linked partly answered my question. I also noticed that after setting stderr to inherit the prompt was shown. The node-pty module is probably the solution to my problem(s), I'll give it a try and keep you updated. – santcleep Jan 17 '22 at 12:16
  • Another issue I encountered was that if you spawn another process inside the shell, for example if you spawn a mysql shell with "mysql -uroot -ptoor" the output is missing again. You can still enter commands like 'exit' and you are back in your shell- though you will not get any output while executing commands in the mysql shell. – santcleep Jan 17 '22 at 12:20
  • Please read that article I link to in my comment to your question about inherit vs. pipe. It explains what is going on. Connecting standard in, standard out, and standard error to the child process with inherit essentially tells bash that you have an interactive terminal and it will switch sending output to the dev/ try stream. – kevintechie Jan 17 '22 at 19:20
  • Because your requirement was that you had to capture the output from the child process you have to use pipe which basically isolates your child process from the parent process so it doesn’t know that you have an interactive terminal attached. – kevintechie Jan 17 '22 at 19:22
  • After trying different approaches, I went back to your comment with the "node-pty module". Sadly, I can't realize my project with just the child_process module since I need a pty to simulate the shell and its features, which is not provied by the child_process module (obviously). I am now using a pty library to simulate the terminal and it works just fine. Thanks for your help! – santcleep Feb 21 '22 at 08:09