142

I got this code from a different SO question, but node complained to use process.stdin.setRawMode instead of tty, so I changed it.

Before:

var tty = require("tty");

process.openStdin().on("keypress", function(chunk, key) {
  if(key && key.name === "c" && key.ctrl) {
    console.log("bye bye");
    process.exit();
  }
});

tty.setRawMode(true);

After:

process.stdin.setRawMode(true);
process.stdin.on("keypress", function(chunk, key) {
  if(key && key.name === "c" && key.ctrl) {
    console.log("bye bye");
    process.exit();
  }
});

In any case, it's just creating a totally nonresponsive node process that does nothing, with the first complaining about tty, then throwing an error, and the second just doing nothing and disabling Node's native CTRL+C handler, so it doesn't even quit node when I press it. How can I successfully handle Ctrl+C in Windows?

0

5 Answers 5

283

If you're trying to catch the interrupt signal SIGINT, you don't need to read from the keyboard. The process object of nodejs exposes an interrupt event:

process.on('SIGINT', function() {
    console.log("Caught interrupt signal");

    if (i_should_exit)
        process.exit();
});

Edit: doesn't work on Windows without a workaround. See here

Sign up to request clarification or add additional context in comments.

2 Comments

For future readers, this question is answered for windows here: stackoverflow.com/a/14861513/2020425
The windows problem is already fixed
36

The NPM module, death, uses SIGINT, SIGQUIT, and SIGTERM.

So basically, all you need to do is:

process.on('SIGINT', () => {});  // CTRL+C
process.on('SIGQUIT', () => {}); // Keyboard quit
process.on('SIGTERM', () => {}); // `kill` command

As a side note, this may actually call SIGINT, SIGQUIT, and SIGTERM numerous times... not sure why, it did for me.

I fixed it by doing this:

let callAmount = 0;
process.on('SIGINT', function() {
    if(callAmount < 1) {
        send.success(`✅ The server has been stopped`, 'Shutdown information', 'This shutdown was initiated by CTRL+C.');
        setTimeout(() => process.exit(0), 1000);
    }

    callAmount++;
});

If all you want to do is detect the interruption keys, just use SIGINT

Edit: I didn't realize this post was very old, oh well, it's helpful to others I guess!

Comments

8

For those who need the functionality, I found death (npm nodule, hah!).

Author also claims it works on windows:

It's only been tested on POSIX compatible systems. Here's a nice discussion on Windows signals, apparently, this has been fixed/mapped.

I can confirm CTRL+C works on win32 (yes, I am surprised).

Comments

-3
process.on('signal', async (signal) => {
    console.log('signal: ', signal);
    if (signal === 'SIGINT') {
        console.log('Received SIGINT. Calling save function...');
        await amazon.saveData();
    }

    process.exit(0);
});

1 Comment

Your answer could be improved by adding more information on what the code does and how it helps the OP.
-8
if (event.key == "ctrl+c") {
    console.log("goodbye");
    break;
}

2 Comments

This won't work. event.key isn't for key combinations, so it will never be anything like ctrl+c.
break only works in for and while loops. Running it in an if statement will cause Node.js to crash. Use process.exit() instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.