Stop Linux Processes Safely with kill
You will finish with a repeatable way to identify a process, ask it to stop, verify what happened, and escalate only when necessary. The examples use the installed procps-ng kill 4.0.4 command. Allow about ten minutes. You need a shell and a process you are authorised to control. Most inspection steps are ordinary user commands; stopping another user's process may require elevated privileges.
The route
Jump straight to the step you need, or tick off Done means at the end.
- 1. Confirm which kill you are using
- 2. Inspect signal names before sending one
- 3. Create a harmless test process
- 4. Ask the process to stop cleanly
- 5. Use signal 0 for a permission and existence check
- 6. Escalate only after TERM fails
- 7. Avoid process-group and all-process traps
- 8. Diagnose the common failures
Safety boundary
A signal changes a running process. Do not experiment with a production service, a process you do not recognise, or a copied PID. The examples use a private sleep process where possible, so you can practise without changing a service.
1. Confirm which kill you are using
Many shells provide a built-in kill. It usually supports the same everyday syntax, but this guide documents the procps command. Check both the selected command and its version:
$ command -v kill
/usr/bin/kill
$ /bin/kill --version
kill from procps-ng 4.0.4
Your path may differ. If command -v kill reports a shell built-in, use /bin/kill for the examples that depend on procps-specific options such as -L. Checkpoint: the command you intend to run is the one whose behaviour you have inspected.
2. Inspect signal names before sending one
The default signal is TERM, also written SIGTERM. It asks a process to terminate cleanly. List the signal names supported by this installation:
$ /bin/kill -l
HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT
CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR SYS
The ordering and available names depend on the platform, so treat the output as authoritative for your machine. To translate a number, pass it as the optional argument to -l:
$ /bin/kill -l 15
TERM
Signals have different meanings. TERM gives the program a chance to close files and release resources. KILL cannot be caught or cleaned up by the target. STOP pauses a process, while CONT resumes one that was stopped. Do not choose a signal by number when a name makes the intent clearer.
3. Create a harmless test process
Start a short-lived process in the background and save its PID immediately. This is unprivileged and changes only your shell's child process:
$ sleep 300 &
[1] 24680
$ test_pid=$!
$ printf 'test PID: %s\n' "$test_pid"
test PID: 24680
The job number and PID are examples and will vary. The shell's $! value is the PID of the most recently started background command. Keep it in a variable rather than retyping a number from a different terminal.
Checkpoint: inspect that PID before sending anything. ps is read-only:
$ ps -o pid=,ppid=,stat=,comm= -p "$test_pid"
24680 2123099 S sleep
You want the expected command name and a live row for the expected PID. If the row is empty or the command is not the one you started, stop. Do not send a signal to that PID.
4. Ask the process to stop cleanly
Send TERM by name. The -- separates options from the PID argument and makes the command boundary easier to review:
$ /bin/kill --signal TERM -- "$test_pid"
$ wait "$test_pid"
$ printf 'exit status: %s\n' "$?"
exit status: 143
A shell commonly reports 128 plus the signal number, so 143 means the child ended after signal 15. The exact status can differ if a wrapper handles the signal. Verify that it is no longer running:
$ ps -p "$test_pid" -o pid=,stat=,comm=
$ printf 'ps status: %s\n' "$?"
ps status: 1
An empty row and non-zero ps status indicate that this PID is no longer present. PIDs are reused, so do not keep signalling a saved number after the original process has gone.
5. Use signal 0 for a permission and existence check
Signal 0 is special: the kernel performs the usual existence and permission checks but does not deliver a signal. It is useful before an operation, but it does not prove that a process is healthy or belongs to the command you expect:
$ /bin/kill -s 0 -- "$test_pid"
/bin/kill: (...) - No such process
$ printf 'check status: %s\n' "$?"
check status: 1
For a live PID, a zero exit status means the check succeeded. A non-zero status can mean that the process does not exist or that your user lacks permission. Use ps to distinguish an absent row from a process owned by another user. Do not jump straight to sudo; first confirm the PID and the required administrative boundary.
6. Escalate only after TERM fails
Some programs ignore TERM, are stuck in a state where they cannot handle it, or need more time to finish. First inspect the same PID again and check the application's own logs or service manager. If you have confirmed that the process must stop, KILL is the forceful option:
$ /bin/kill --signal KILL -- PID_TO_STOP
$ ps -p PID_TO_STOP -o pid=,stat=,comm=
Replace PID_TO_STOP only after checking it with ps. The command normally prints nothing when it succeeds. KILL prevents the process from running cleanup code and can leave temporary files, locks, transactions or child processes behind. It is service-disrupting and may lose in-memory data. There is no undo for a delivered KILL; recovery means restarting the program and repairing whatever state it left behind.
7. Avoid process-group and all-process traps
A negative PID selects a process group, not one ordinary process. The process-group ID appears in ps output when requested:
$ ps -o pid=,pgid=,comm= -p PID_TO_INSPECT
24680 24680 sleep
Never turn a copied PID into a negative number casually. A group can contain a shell, workers and unrelated commands. The procps manual also gives -1 a special meaning: all processes you can signal except the kill process itself and init. This is an extreme, destructive action. Do not run kill -1 or kill -9 -1 as a test, from a service account, or on a system whose recovery you cannot control.
If you need to stop a service, use its service manager and its documented unit rather than guessing at a process group. For systemd, inspect first with systemctl status UNIT_NAME; changing or stopping the unit is a separate administrative action that needs a maintenance decision and a recovery plan.
8. Diagnose the common failures
kill: usage... usually means the command line was malformed. Check the signal spelling and that the PID is numeric. If a PID begins with a hyphen, use -- or resolve why it was produced before proceeding.
No such process means the PID is not currently valid for the requested operation. Re-run ps immediately; the process may have exited, or the PID may have been copied incorrectly. Operation not permitted means your user cannot signal that process. Confirm ownership, then use the approved administrative route. A successful signal command is not proof that the application performed the shutdown you wanted, so verify the process and its service state afterwards.
Done means
- You confirmed the procps-ng version and, where relevant, used
/bin/killinstead of a shell built-in. - You inspected the exact PID with
psimmediately before signalling it. - You used named
TERMfirst and verified whether the process exited. - You understand that signal 0 checks existence and permission without stopping anything.
- You reserve
KILL, negative PIDs and-1for deliberate, reviewed operations. - You have a recovery plan before stopping a service or using a signal that cannot be undone.