| |

LFCS 59 ๐Ÿง Signals โ€” Overview and Use

โฑ๏ธ Estimated read: 11 min | |

A signal is a limited form of inter-process communication: a notification delivered to a process by the kernel or by another process. It interrupts whatever the process is doing and invokes one of three dispositionsโ€”the default action, an ignore, or a handler function that the process installed. The default action is signal-specific. SIGTERM terminates the process. SIGKILL terminates it and cannot be caught. SIGHUP terminates it unless the process is designed to survive. SIGSTOP stops it. The list is long, and the LFCS exam expects you to know the common ones, the signals that cannot be caught, and the tools that send them.

The distinction that matters most for the exam and for daily administration is between SIGTERM and SIGKILL. SIGTERM is the polite request: the process can catch it, clean up its resources, and exit gracefully. SIGKILL is the kernel-enforced termination: the process cannot catch it, block it, or ignore it, and it has no opportunity to save data or close connections . The rule is to always try SIGTERM first and escalate to SIGKILL only when the process is unresponsive. The same rule applies to the kill command’s default, which is SIGTERM, not SIGKILL .

Key point: A signal is a notification with a default disposition that the process can change, except for SIGKILL and SIGSTOP, which cannot be caught, blocked, or ignored . kill sends SIGTERM by default; kill -9 sends SIGKILL; kill -l lists the signal names and numbers.


Why signals work the way they do

The asynchronous notification problem. A process cannot poll for every possible event. The kernel needs a way to tell a process that something happenedโ€”a child exited, a timer expired, a terminal hung up, a user pressed Ctrl+Cโ€”without the process having to ask. The signal is that mechanism. It is asynchronous, it is delivered by the kernel, and it interrupts the process’s normal execution. The process can choose how to respond by installing a handler or by ignoring the signal.

The default-action problem. Every signal has a default action, and the action is not always “terminate.” SIGCHLD is ignored by default, because the parent is expected to wait for the child. SIGCONT continues a stopped process. SIGSTOP stops it. SIGTSTP is the terminal-generated stop, and it is different from SIGSTOP because it can be caught. SIGWINCH is ignored, because most programs do not care that the terminal was resized . Knowing the default action is how you predict what a signal will do to a process that has not installed a handler.

The uncatchable-signal problem. SIGKILL and SIGSTOP are the exceptions. The kernel enforces them regardless of what the process wants. SIGKILL exists so that an unresponsive process can always be terminated. SIGSTOP exists so that a process can always be stopped for inspection or job control. If these signals could be caught, a malicious or buggy process could become unkillable, and the system would have no way to recover it .

The terminal problem. The terminal driver generates signals based on keyboard input. Ctrl+C sends SIGINT to the foreground process group. Ctrl+Z sends SIGTSTP. Ctrl+\ sends SIGQUIT, which terminates with a core dump. These are not sent by the shell; they are sent by the terminal driver, and they go to the foreground process group, not to a specific PID. This is why a background job is immune to Ctrl+Cโ€”it is not in the foreground group, so the terminal driver does not send it the signal.


a. The common signals and their numbers

The signal numbers are architecture-dependent in some cases, but the common ones are consistent on x86 and ARM. The names are the portable identifier, and the numbers are the shortcut.

SignalNumberDefault ActionMeaning
SIGHUP1TerminateHangup detected on controlling terminal or death of controlling process
SIGINT2TerminateInterrupt from keyboard (Ctrl+C)
SIGQUIT3Core dumpQuit from keyboard (Ctrl+)
SIGKILL9TerminateKill signal; cannot be caught, blocked, or ignored
SIGTERM15TerminateTermination signal
SIGSTOP19StopStop process; cannot be caught, blocked, or ignored
SIGCONT18ContinueContinue if stopped
SIGTSTP20StopStop typed at terminal (Ctrl+Z)

The numbers in this table are the x86 and ARM values. SIGSTOP is 19 on x86 and ARM, and SIGCONT is 18. On other architectures, the numbers can differ, which is why the signal name is the safer form in scripts and documentation .

The SIGKILL and SIGSTOP rows are the ones to remember. The kernel enforces them regardless of the process’s disposition. Every other signal can be caught, ignored, or blocked by the process, and the default action is only the fallback when the process has not chosen otherwise .


b. Sending signals with kill

The kill command is the primary tool for sending a signal. Its name is misleadingโ€”it sends any signal, not just the terminating one. The default signal is SIGTERM (15), not SIGKILL (9) .

# Send SIGTERM (the default) to a process by PID
# The process can catch it and clean up
kill 1234

# Send SIGKILL to a process that ignored SIGTERM
# The process cannot catch or ignore SIGKILL
kill -9 1234

# Send SIGHUP to a daemon to ask it to reload its configuration
# Many daemons catch SIGHUP and re-read their config files
kill -HUP 1234

# Send SIGSTOP to pause a process
# The process is stopped, not terminated
kill -STOP 1234

# Send SIGCONT to resume a stopped process
kill -CONT 1234

# List all signal names and numbers
kill -l

# Convert a signal number to a name
kill -l 9
# Output: KILL

The signal can be specified by name (-HUP, -SIGKILL, -KILL), by number (-1, -9, -15), or by the -s flag (-s TERM). The kill -l command lists the supported names, and kill -l <number> converts a number to a name . The kill -L variant prints a table with descriptions .

The kill command is also a shell builtin, and the builtin’s behavior can differ from the external /bin/kill. The GNU Coreutils manual warns that using an unadorned kill in a script may get the shell’s version rather than the external command, and recommends env kill to bypass the shell’s builtin when the exact behavior matters .


c. The process group and the %job reference

A signal can be sent to a process group rather than a single process. The negative PID is the process group ID. kill -TERM -1234 sends SIGTERM to every process in the group with PGID 1234. The %1 form is the job control reference: kill %1 sends the signal to the job’s process group .

# Start a background job
sleep 300 &
# Output: [1] 12345

# Send SIGTERM to the job by its job number
# The signal goes to the entire process group
kill %1

# The process group ID is the PID of the job's leader
# For a simple command, the leader is the command itself
# The negative PID sends to the group
kill -TERM -12345

The %1 reference is the shell’s job number, and the shell translates it to the process group ID. The negative PID is the raw form, and it is what the shell uses internally. The kill command’s PID argument rules are: a positive PID targets that process, 0 targets the current process group, -1 targets all processes the user can signal (except the kill process and init), and a negative PID less than -1 targets the process group with that absolute value .

The signal 0 is a special case. It does not send a signal, but it performs the permission and existence checks. kill -0 1234 succeeds if the process exists and the user has permission to signal it, and fails otherwise. This is the shell’s way to check whether a PID is alive without sending a signal that changes the process’s state .


Complete Example Session

The following session starts a process, sends SIGTERM, verifies it is gone, and demonstrates the SIGKILL escalation and the SIGSTOP/SIGCONT pair.

# ============================================
# PART 1: START A PROCESS
# ============================================
# Start a long-running sleep in the background
sleep 300 &
# Output: [1] 12345

# The PID is 12345
PID=12345

# ============================================
# PART 2: SEND SIGTERM
# ============================================
# Send SIGTERM (the default)
# The sleep process does not catch it, so it terminates
kill $PID

# Verify the process is gone
ps -p $PID
# Output: PID TTY TIME CMD
# (no process)

# ============================================
# PART 3: THE SIGKILL ESCALATION
# ============================================
# Start a process that ignores SIGTERM
# The trap command catches SIGTERM and does nothing
trap '' TERM
sleep 300 &
PID2=$!

# Send SIGTERM; the process ignores it
kill $PID2
# The process is still running
ps -p $PID2
# Output: PID TTY TIME CMD
#         12346 pts/0 00:00:00 sleep

# Send SIGKILL; the kernel terminates it
kill -9 $PID2
# The process is gone
ps -p $PID2
# Output: (no process)

# ============================================
# PART 4: SIGSTOP AND SIGCONT
# ============================================
# Start a process
sleep 300 &
PID3=$!

# Send SIGSTOP; the process is paused
kill -STOP $PID3
# The process is in the T (stopped) state
ps -o pid,stat,comm -p $PID3
# Output: PID STAT COMMAND
#         12347 T    sleep

# Send SIGCONT; the process resumes
kill -CONT $PID3
# The process is running again
ps -o pid,stat,comm -p $PID3
# Output: PID STAT COMMAND
#         12347 S    sleep

# ============================================
# PART 5: THE SIGNAL LIST
# ============================================
# List all signals
kill -l

# Convert a number to a name
kill -l 15
# Output: TERM

# ============================================
# PART 6: CLEAN UP
# ============================================
kill $PID3

The six parts cover starting a process, sending SIGTERM, the SIGKILL escalation against a process that ignores SIGTERM, the SIGSTOP/SIGCONT pair, the signal list, and cleanup. What the session demonstrates is that SIGTERM is the default and the polite request, SIGKILL is the kernel-enforced termination, and SIGSTOP/SIGCONT are the pause and resume pair.


Quick Reference

Common Signals

SignalNumberDefaultCan Catch?
SIGHUP1TerminateYes
SIGINT2TerminateYes
SIGQUIT3Core dumpYes
SIGKILL9TerminateNo
SIGTERM15TerminateYes
SIGSTOP19StopNo
SIGCONT18ContinueYes
SIGTSTP20StopYes

kill Syntax

CommandEffect
kill PIDSend SIGTERM
kill -9 PIDSend SIGKILL
kill -HUP PIDSend SIGHUP
kill -STOP PIDSend SIGSTOP
kill -CONT PIDSend SIGCONT
kill -lList signals
kill -0 PIDCheck if process exists

Process Group Targeting

FormTarget
kill -TERM -PGIDProcess group PGID
kill %1Job 1’s process group
kill 0Current process group
kill -1All processes the user can signal

Best Practices

โœ… Do This:

# Try SIGTERM first
kill 1234

# Escalate to SIGKILL only when needed
kill -9 1234

# Use SIGHUP to reload daemon configuration
kill -HUP 1234

# Use the signal name in scripts
kill -TERM "$PID"

โŒ Don’t Do This:

# Use SIGKILL as the first attempt
kill -9 1234 # may corrupt data

# Assume the signal number is portable
kill -19 1234 # SIGSTOP on x86, different elsewhere

# Forget the shell builtin difference
kill -l # may list the builtin's signals, not /bin/kill's

Common Pitfalls

PitfallWhy It HappensFix
Process does not dieUsed SIGTERM on a process that ignores itkill -9
Signal number wrongArchitecture-dependent numbersUse the signal name
Job reference failsNo job control in non-interactive shellUse the PID
kill -0 failsProcess does not exist or no permissionCheck the PID and user
SIGKILL loses dataNo cleanup opportunityTry SIGTERM first

Real-World Examples

1. Terminate a process

kill 1234

2. Force terminate

kill -9 1234

3. Reload a daemon

kill -HUP 1234

4. Pause a process

kill -STOP 1234

5. Resume a process

kill -CONT 1234

6. List signals

kill -l

7. Convert number to name

kill -l 15

8. Check if a process exists

kill -0 1234

9. Kill a job

kill %1

10. Kill a process group

kill -TERM -1234

Visual

Signal Dispositions

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Signal delivered to process                 โ”‚
โ”‚         โ”‚                                    โ”‚
โ”‚         โ–ผ                                    โ”‚
โ”‚  Disposition?                                โ”‚
โ”‚    โ”œโ”€ Default action (Term, Stop, Ign, Core) โ”‚
โ”‚    โ”œโ”€ Ignore (SIG_IGN)                       โ”‚
โ”‚    โ””โ”€ Handler (caught)                       โ”‚
โ”‚                                              โ”‚
โ”‚  SIGKILL and SIGSTOP always use default      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

SIGTERM vs SIGKILL

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  SIGTERM (15)                                โ”‚
โ”‚  โ†’ catchable, process can clean up           โ”‚
โ”‚  โ†’ polite termination request                โ”‚
โ”‚                                              โ”‚
โ”‚  SIGKILL (9)                                 โ”‚
โ”‚  โ†’ not catchable, not blockable              โ”‚
โ”‚  โ†’ kernel terminates immediately             โ”‚
โ”‚  โ†’ no cleanup                                โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

SIGSTOP / SIGCONT

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Running                                     โ”‚
โ”‚         โ”‚                                    โ”‚
โ”‚         โ–ผ  SIGSTOP                           โ”‚
โ”‚  Stopped (T state)                           โ”‚
โ”‚         โ”‚                                    โ”‚
โ”‚         โ–ผ  SIGCONT                           โ”‚
โ”‚  Running                                     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Terminal Signals

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Ctrl+C  โ†’ SIGINT  โ†’ terminate               โ”‚
โ”‚  Ctrl+Z  โ†’ SIGTSTP โ†’ stop                    โ”‚
โ”‚  Ctrl+\  โ†’ SIGQUIT โ†’ core dump               โ”‚
โ”‚                                              โ”‚
โ”‚  Sent to the foreground process group        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
Signal purposeAsynchronous notification to a process
Default actionTerminate, stop, ignore, or core dump
UncatchableSIGKILL, SIGSTOP
kill defaultSIGTERM (15)
Force terminatekill -9
Reload daemonkill -HUP
Pausekill -STOP
Resumekill -CONT
List signalskill -l
Check existencekill -0

Key takeaways:

  • A signal is a notification with a default disposition. The process can catch, ignore, or block most signals, but not SIGKILL or SIGSTOP, which the kernel enforces regardless of the process’s wishes .
  • SIGTERM is the polite request; SIGKILL is the forced termination. The default for kill is SIGTERM, and the correct escalation is to try it first and use kill -9 only when the process does not respond .
  • SIGHUP is used to reload daemon configuration. Many daemons catch it and re-read their config files rather than terminating. The name comes from “hangup,” but the modern use is often reload.
  • SIGSTOP and SIGCONT are the pause/resume pair. SIGSTOP stops the process and cannot be caught. SIGCONT resumes it. They are the tools for pausing a process without terminating it.
  • The signal name is more portable than the number. The numbers are architecture-dependent, and the name is the stable identifier .
  • The kill command is also a shell builtin. The builtin’s behavior can differ from /bin/kill, and the GNU documentation recommends env kill when the exact behavior matters .

Remember: Signals are the kernel’s way of telling a process that something happened. The process can choose how to respond for most signals, but SIGKILL and SIGSTOP are the exceptions that the kernel enforces. The kill command sends the signal, and its default is SIGTERM, not SIGKILL. The exam expects you to know the common signals, the uncatchable ones, the kill syntax, and the difference between the polite SIGTERM and the forced SIGKILL. The SIGHUP reload pattern and the SIGSTOP/SIGCONT pause pair are the operational patterns that appear in daily administration.


Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!