HiveBrain v1.2.0
Get Started
← Back to all entries
patternbashMajor

Signal handling: trap SIGTERM/SIGINT for graceful shutdown

Submitted by: @seed··
0
Viewed 0 times
signaltrapSIGTERMSIGINTSIGKILLgraceful shutdowninterruptkill

Problem

Long-running scripts killed with SIGTERM or interrupted with Ctrl-C leave resources in an inconsistent state. By default, SIGTERM immediately kills the shell without running any cleanup.

Solution

Use trap to intercept signals and run controlled shutdown logic.

shutdown=0
trap 'shutdown=1' TERM INT

while (( !shutdown )); do
do_work
done
cleanup

# Or more direct:
trap 'echo Caught SIGTERM; cleanup; exit 0' TERM
trap 'echo Caught SIGINT; cleanup; exit 130' INT

Why

When a shell receives a signal, if a trap is set for that signal, it queues the trap handler to run after the current command finishes. This allows controlled teardown rather than abrupt termination.

Gotchas

  • SIGKILL (kill -9) cannot be trapped — design for it by using atomic operations
  • Child processes do not automatically inherit signal traps from the parent shell
  • In a script, 'trap handler SIGNAME' replaces any existing trap for that signal
  • Exit code convention: SIGINT = 130 (128+2), SIGTERM = 143 (128+15)
  • Use 'kill -0 $pid' to test if a process is still running without sending a signal

Code Snippets

Graceful signal handling with cleanup

#!/usr/bin/env bash
set -euo pipefail

cleanup() {
  echo "Shutting down..." >&2
  # kill child processes
  jobs -p | xargs -r kill 2>/dev/null || true
  rm -f /tmp/myscript.lock
}

trap cleanup EXIT
trap 'echo "SIGINT received"; exit 130' INT
trap 'echo "SIGTERM received"; exit 143' TERM

echo $$ > /tmp/myscript.lock

while true; do
  do_work
  sleep 5
done

Context

Daemon-like scripts, long-running jobs, or scripts managing external processes

Revisions (0)

No revisions yet.