0

I'm running a Node.js script that creates a child process using the spawn function from the child_process module. The child process runs the zsh shell and prompts the user to enter a name using the read command. However, I can't see the prompt message in the output of the child process.

Here's my code:

const { spawn } = require('child_process');

let child;

async function executeCommandOrSendInput(commandOrInput) {
  if (!child || child.exitCode !== null) {
    console.log('Creating new child process');
    child = spawn('zsh', [], { stdio: 'pipe' });

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

    child.stderr.on('data', (data) => {
      console.error(`Error: ${data}`);
    });

    child.on('close', (code) => {
      console.log(`Child process exited with code ${code}`);
    });
  }

  console.log('Sending command or input:', commandOrInput);
  child.stdin.write(commandOrInput + '\n');
}

(async () => {
  try {
    await executeCommandOrSendInput('read "name?name?" ;echo $name > /tmp/thename.txt; echo done');
    await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for 1 second
    await executeCommandOrSendInput('my_name');
    await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for 1 second
    child.stdin.end(); // End the child process
  } catch (error) {
    console.error('An error occurred:', error);
  }
})();

The output is

Creating new child process
Sending command or input: read "name?name?" ;echo $name > /tmp/thename.txt; echo done
Sending command or input: my_name
Output: done

Child process exited with code 0

I am using a strange zsh version of read which apparently puts the message before the ?.

When I run the script, I expect to see the name? prompt message in the output of the child process, but it's not there. How can I see the full output of the commands. When I run in zsh, I see:

% read "name?name?" ;echo $name > /tmp/thename.txt; echo done
name?my_name
done

The file I'm creating in the tmp directory does have the correct output

umop
  • 2,122
  • 2
  • 18
  • 22
  • I discovered that the prompt for read goes to stderr and not stdout, but I am logging stderr as well, and the handler never gets triggered – umop Apr 08 '23 at 08:12
  • From the [man page](https://zsh.sourceforge.io/Doc/Release/Shell-Builtin-Commands.html#index-read) "If the first argument contains a ‘?’, the remainder of this word is used as a prompt on standard error when the shell is interactive." Notice the last 5 words in that sentence. When the shell's I/O are pipes (in particular stdin is not a terminal) as is the case for nodejs child_process it is not interactive. – dave_thompson_085 Apr 08 '23 at 09:37
  • Understood that stdin is not a terminal. Is there a good way to accomplish what I'm trying to do here? Even beyond the bounds of nodeJS or child_process. I have opened a separate question (https://stackoverflow.com/questions/75964169/programmatically-emulating-and-capturing-a-shell-as-a-terminal) for this since it is diverging from what this question is asking – umop Apr 09 '23 at 20:26

0 Answers0