Handle SIGINT Cleanup in a CLI
Trap interrupt signals to remove temporary files and flush progress so Ctrl-C does not leave a broken state.
Task
Install signal handlers that clean up temporary resources before exiting.
When to use this
Interrupting a long CLI run leaves partial temp files and a half-written output that confuses the next run.
Prerequisites
- A CLI that writes temporary files
- A way to register signal handlers
- A cleanup routine
Steps
1. Register handlers that clean up then exit.
const tmp = makeTempDir();
let done = false;
function cleanup() {
if (done) return; done = true;
rmSync(tmp, { recursive: true, force: true });
process.exit(130);
}
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);Expected output: Ctrl-C removes temporary resources and exits with the conventional code.
2. Verify no leftovers remain after an interrupt.
tool long-job &
sleep 1 && kill -INT %1
ls /tmp | grep tool-tmp || echo 'no leftovers'Expected output: The temp directory is gone, proving cleanup ran on interrupt.
Troubleshooting
Problem
Cleanup runs twice
Solution
Guard cleanup with an idempotency flag so both SIGINT and SIGTERM are safe.
Problem
Exit code wrong
Solution
Exit with 130 for SIGINT so scripts can distinguish interruption.
Limitations
- SIGKILL cannot be trapped.
- Async cleanup in handlers is limited.
- Requires careful exit code semantics.
What this recipe does
Install signal handlers that clean up temporary resources before exiting.
Interrupting a long CLI run leaves partial temp files and a half-written output that confuses the next run.
Prerequisites
- A CLI that writes temporary files
- A way to register signal handlers
- A cleanup routine
Procedure
- Register handlers that clean up then exit.
const tmp = makeTempDir();
let done = false;
function cleanup() {
if (done) return; done = true;
rmSync(tmp, { recursive: true, force: true });
process.exit(130);
}
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);
Expected result: Ctrl-C removes temporary resources and exits with the conventional code.
- Verify no leftovers remain after an interrupt.
tool long-job &
sleep 1 && kill -INT %1
ls /tmp | grep tool-tmp || echo 'no leftovers'
Expected result: The temp directory is gone, proving cleanup ran on interrupt.
How to confirm it worked
Run the commands above and confirm every expected result in order. If a step does not produce the stated output, use the troubleshooting notes before continuing. A passing run shows interrupting the CLI leaves no temporary files and returns the conventional exit code.
Troubleshooting
Cleanup runs twice — Guard cleanup with an idempotency flag so both SIGINT and SIGTERM are safe.
Exit code wrong — Exit with 130 for SIGINT so scripts can distinguish interruption.
Limitations
- SIGKILL cannot be trapped.
- Async cleanup in handlers is limited.
- Requires careful exit code semantics.