When terminating a systemd service, there are fundamental differences between using the raw kill
command versus systemctl kill
:
# Direct SIGKILL using process ID
kill -SIGKILL 3645
# Systemd-aware termination
systemctl kill --signal=SIGKILL service_name
Process Tracking: systemctl maintains service state in its control group (cgroup). A raw kill bypasses this tracking.
Cleanup Handling: systemctl initiates proper service cleanup routines including:
- Updating service state in journald
- Executing ExecStopPost commands
- Handling service dependencies
Service Recovery: After a raw kill:
systemctl status my_service
# Shows "active (exited)" rather than "failed"
Logging Example:
journalctl -u my_service -n 20
# Missing proper termination entries when using raw kill
For emergency termination while maintaining systemd integration:
# Preferred method
systemctl kill --signal=SIGKILL my_service
# Alternative when PID is known but service name isn't
systemctl kill --signal=SIGKILL --pid=3645
Reserve raw kill
only for:
- Debugging scenarios
- When systemd itself is unresponsive
- Investigating process behavior
When terminating a systemd service, there are fundamental architectural differences between using the raw kill
command versus systemctl kill
:
# Direct process termination
kill -SIGKILL 3645
# Systemd-aware termination
systemctl kill --signal=SIGKILL service_name
Systemd maintains service state in its control group (cgroup) hierarchy. Direct kill
commands bypass this management layer:
- kill -SIGKILL 3645: Only terminates the immediate process, potentially leaving child processes orphaned
- systemctl kill: Sends signals to the entire cgroup, ensuring complete process tree termination
Consider a web server with worker processes:
# After systemctl start nginx
ps aux | grep nginx
root 3645 0.0 0.5 123456 7890 ? Ss 10:00 0:00 nginx: master
www-data 3646 0.0 0.3 123456 5678 ? S 10:00 0:00 nginx: worker
www-data 3647 0.0 0.3 123456 5678 ? S 10:00 0:00 nginx: worker
# Using kill -SIGKILL 3645 (master only)
kill -SIGKILL 3645
ps aux | grep nginx
www-data 3646 0.0 0.3 123456 5678 ? S 10:00 0:00 nginx: worker
www-data 3647 0.0 0.3 123456 5678 ? S 10:00 0:00 nginx: worker
# Using systemctl kill
systemctl kill --signal=SIGKILL nginx
ps aux | grep nginx
# No remaining processes
Systemd maintains service state in its journal. Direct kills create inconsistencies:
journalctl -u nginx --no-pager
# After kill -SIGKILL:
May show "active (running)" despite terminated process
# After systemctl kill:
Proper state transition to "failed" or "inactive"
- Always prefer
systemctl kill
for managed services - Use direct
kill
only for debugging or when systemd is unresponsive - Combine with
systemctl reset-failed
if states become inconsistent - Consider
SIGTERM
beforeSIGKILL
for graceful shutdowns
systemctl kill
offers precise control:
# Send SIGUSR1 to main process only
systemctl kill --signal=SIGUSR1 --kill-who=main service
# Send SIGTERM to control group
systemctl kill --signal=SIGTERM service
# View current signal handlers
systemctl show -p KillSignal,KillMode service