Linux Lifehack

Как найти и завершить зависший процесс

Процесс не отвечает и держит ресурсы. Как его найти, чем отличается SIGTERM от SIGKILL и почему не стоит сразу бить -9.

Проверено: Ubuntu 24.04, Debian 12
Как найти и завершить зависший процесс

Разница между kill и kill -9 — это разница между «закрой файлы и выйди» и «умри немедленно». Вторая команда оставляет за собой мусор.

Найти процесс

По имени:

pgrep -a nginx

Ключ -a показывает полную командную строку — удобно, когда одинаковых процессов несколько.

По занятому порту:

sudo ss -tlnp | grep :8080

По открытому файлу:

sudo lsof /path/to/file

Топ по загрузке CPU:

ps aux --sort=-%cpu | head -10

Топ по памяти:

ps aux --sort=-%mem | head -10

Завершить правильно

Порядок действий — от мягкого к жёсткому.

Шаг 1. SIGTERM — вежливая просьба завершиться. Процесс закроет файлы, сбросит буферы, отпустит блокировки:

kill PID

Подождите 5–10 секунд и проверьте:

ps -p PID

Шаг 2. SIGKILL — только если SIGTERM не сработал:

kill -9 PID

Предупреждение. SIGKILL нельзя перехватить. База данных не успеет закрыть транзакцию, файл не допишется, временные файлы останутся. Для СУБД это прямой путь к повреждению данных — всегда пробуйте SIGTERM первым.

По имени вместо PID

pkill nginx
pkill -9 nginx

Точное совпадение имени, а не подстрока:

pkill -x nginx

Только процессы конкретного пользователя:

pkill -u www-data nginx

Предупреждение. pkill без -x ищет по подстроке. pkill java убьёт все java-процессы на машине. Перед выполнением проверьте, что попадёт под удар: pgrep -a java.

Процесс в состоянии D

Если в ps процесс имеет статус D (uninterruptible sleep), его не убьёт даже SIGKILL — он ждёт ответа от ядра, обычно от диска или сетевой файловой системы.

ps -eo pid,stat,comm | awk '$2 ~ /D/'

Причину показывает стек ядра:

sudo cat /proc/PID/stack

Здесь помогает только устранение причины: восстановить сетевую шару, дождаться диска, в крайнем случае перезагрузить машину.

Если процесс — сервис

Не убивайте его напрямую — systemd перезапустит по политике Restart или пометит как failed:

sudo systemctl stop имя-сервиса

Итог

Находим через pgrep -a или ss -tlnp. Завершаем через kill, ждём, и только потом kill -9. Сервисы останавливаем через systemctl, процессы в состоянии D не убиваются вообще.