Stop your scripts from eating your process signal handling for breakfast
By Saket Jain Published Linux/Unix
Stop your scripts from eating your process signal handling for breakfast
Technical Briefing | 8/30/2026
You spend hours writing a complex bash script, add some error traps, and ship it. But then you realize that every time you send a SIGINT to kill it, it stays alive longer than a vampire in a movie. You check the code, and everything looks sane. The problem isn’t your logic; it’s how bash treats signal propagation when you are running external commands in the foreground.
The subtle difference between waiting and executing
When you run a command in a shell script, your script doesn’t just pass the signal along automatically. If you’ve got a trap set to clean up tmp files or log the exit, the shell wait-states can get stuck. If a child process is running, the shell often stops listening to your interrupts until that child returns. It is incredibly frustrating to mash Ctrl+C and have the shell just stare at you while the sub-process continues churning through a massive log file.
trap 'echo Caught interrupt; exit 1' SIGINT
long_running_process &
wait $!
- Always use wait to explicitly allow the shell to handle signals while background jobs are running
- Don’t rely on default signal behavior if you are wrapping commands in loops or pipes
- Test your traps by sending SIGTERM from a separate terminal to ensure your cleanup routines actually fire
Most of the time, we forget that the shell is a process manager first and a language second. By backgrounding your heavy lifting and using wait, you keep the trap mechanism in control of the parent shell’s signal table. It sounds simple, but I have seen production automation systems lock up for hours because they were waiting on a hung child process that wouldn’t acknowledge a kill signal because the parent shell had effectively muted itself. Get into the habit of trapping and waiting explicitly, and you will save yourself a lot of head-scratching when the automation stack starts misbehaving.
