Przejdลบ do treล›ci

๐Ÿ›‘ Extended Traps and Signals

Signals are asynchronous notifications sent to processes. Traps let you intercept and handle them gracefully.

๐Ÿงญ Common Signals

Signal Number Description Default Action
SIGINT 2 Ctrl+C โ€” Interrupt Terminate
SIGTERM 15 Termination request Terminate
SIGKILL 9 Force kill (cannot trap) Terminate
SIGHUP 1 Hangup (terminal closed) Terminate
SIGSTOP 19 Stop process (cannot trap) Stop
SIGCONT 18 Continue stopped process Continue
SIGUSR1 10 User-defined 1 Terminate
SIGUSR2 12 User-defined 2 Terminate

๐Ÿงช Basic Trap Usage

Catch Ctrl+C

1
2
3
4
5
6
trap 'echo "Interrupted!"; exit 1' INT

while true; do
    sleep 1
    echo "Running..."
done

Press Ctrl+C โ†’ prints "Interrupted!" and exits cleanly.

Multiple Signals

1
2
3
4
5
6
7
cleanup() {
    echo "Cleaning up..."
    rm -f /tmp/myapp.lock
    exit 0
}

trap cleanup INT TERM EXIT

This catches: - Ctrl+C (INT) - kill command (TERM) - Any exit (EXIT)


๐Ÿง  Ignoring Signals

Prevent accidental termination:

1
2
trap '' INT    # Ignore Ctrl+C
trap '' TERM   # Ignore termination requests

Useful for critical sections:

1
2
3
4
5
6
7
8
critical_section() {
    trap '' INT TERM   # Protect during critical work

    # Sensitive operations
    write_to_database

    trap - INT TERM    # Restore default handling
}

๐Ÿงช Resetting Traps

Restore default behavior:

1
2
trap - INT    # Reset INT to default
trap -        # Reset all traps

Check current trap:

1
trap -p INT   # Shows what INT trap is set to

๐Ÿง  Practical Use Cases

Graceful Shutdown

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
shutdown_requested=false

graceful_shutdown() {
    echo "Shutdown signal received..."
    shutdown_requested=true
}

trap graceful_shutdown TERM INT

while [ "$shutdown_requested" = false ]; do
    process_next_job
    sleep 1
done

echo "Performing final cleanup..."
cleanup_resources
exit 0

Temporary Signal Handlers

1
2
3
4
5
6
7
8
9
pause_processing() {
    trap 'echo "Paused. Resume with fg."' TSTP
    kill -STOP $$   # Pause this process
}

resume_processing() {
    trap - TSTP
    kill -CONT $$   # Resume this process
}

๐Ÿงช Sending Signals to Processes

1
2
3
4
5
6
7
8
# Find process by name
pid=$(pgrep nginx | head -1)

# Send signals
kill -TERM $pid   # Graceful termination
kill -KILL $pid   # Force kill (last resort)
kill -HUP $pid    # Reload config (common for daemons)
kill -USR1 $pid   # Custom action (e.g., rotate logs)

Check if process responded:

1
kill -0 $pid 2>/dev/null && echo "Process exists" || echo "Process gone"

๐Ÿง  Signal Handling in Functions

Traps are global โ€” they affect the entire shell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
setup_trap() {
    trap 'cleanup' EXIT
}

cleanup() {
    echo "Cleaning up from $FUNCNAME"
}

setup_trap
# cleanup will run when script exits, even from nested functions

๐Ÿงช Debugging Signal Issues

Trace signal delivery:

1
trap 'echo "Received signal: $1"' DEBUG

Or use strace:

1
strace -e trace=signal ./myscript.sh

๐Ÿงพ Summary

  • Trap INT, TERM, EXIT for graceful shutdowns.
  • Use trap '' to protect critical sections.
  • SIGKILL and SIGSTOP cannot be trapped.
  • Send custom signals with kill -USR1, etc.
  • Always clean up resources in trap handlers.
  • Test signal handling under load.

๐Ÿ‘‰ Continue to: Subprocesses and Subshells