Search code examples
node.jssh

Why writing CTRL+C to child process stdin does not terminate process in Node.js while piping it does?


I have a function that I use for testing a command line application. It uses Node.js child_process.exec to run shell commands, like this:

const proc = child_process.exec(command, { env, timeout }, (error) =>
  errorHandler(error)
);

I then listen to events from proc.stdout and respond to prompts by writing to proc.stdin. I would like to pass SIGINT signal to the child process by writing ASCII characters representing CTRL + C to gracefully stop the process. I have tried '^C' and '\x03' but they don't work. However, piping these characters to the command works:

child_process.exec(`printf '^C' | command`);

What is the difference between these two approaches? Why writing to stdin doesn't work while piping does?

Note! I'm using the default /bin/sh in Ubuntu (dash). Neither approach works on Windows.


Solution

  • Here is the problem, the text ^C doesn't terminate anything, it's in fact meaningless.

    What kills a process is sending the SIGINT signal. Now in a terminal CTRL+C or ^C is a shortcut for sending the SIGINT signal, however, what you are doing is just sending a text.

    If you want to kill the process properly you must send the SIGINT signal. You can do that using this code child_process.kill('SIGINT');