Trap In Linux

trap — 0 to Hero

What it is

trap tells a script: "when this signal happens, run this instead of just dying."

trap 'command_or_function' SIGNAL

Register it before the code you want protected. It only catches things that happen after it's set — not before.

The signals that actually matter (daily use)

Signal Fires when
INT Ctrl+C
TERM plain kill PID (no -9)
HUP terminal/SSH connection drops
EXIT script ends, for any reason — success, error, or interrupt

kill -9 (SIGKILL) can never be trapped. That's by design, not a bug.

Two ways to write it — same thing

Inline — fine for one or two quick commands:

trap 'echo "stopped"; rm -f *.tmp' INT

Function — cleaner once cleanup has multiple steps:

cleanup() {
    echo "Interrupted — cleaning up."
    rm -f *.tmp
    exit 1
}
trap cleanup INT

The function must be defined before the trap line — trap just calls a name, it doesn't know what that name means until it's already been declared.

Realistic defaults

  • Casual script, just want Ctrl+C handled: trap cleanup INT
  • Anything that matters (backups, deploys): trap cleanup INT EXIT → EXIT covers crashes too, not just manual interrupts.

Real example (from a health-check script)

#!/bin/bash

cleanup() {
    echo ""
    echo "Interrupted — stopping health check."
    exit 1
}

trap cleanup INT TERM

services="nginx redis-server mysql"

for service in $services; do
    if systemctl is-active --quiet "$service"; then
        echo "Ok: $service"
    else
        echo "$service : DOWN - restarting"
        sudo systemctl restart "$service"
    fi
done

echo "Health check complete."

Ctrl+C mid-loop now prints a clean message and exits — instead of dying silently mid-restart.

The one mistake that breaks it

for service in $services; do
    ...
done

trap cleanup INT   # too late — loop already ran unprotected

trap protects nothing before its own line. Always put it at the top.

Not trap's job

  • kill -9 handling → impossible, not a trap limitation
  • Running something on every reboot → that's crontab -e + @reboot, unrelated system
  • Retrying a failed command → that's &&/|| or a loop, not trap

trap has exactly one job: catch a signal, run a reaction. That's the whole tool.

添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论