Каждая программа в Linux работает как один или несколько процессов. Иногда процесс зависает, потребляет слишком много ресурсов или просто нуждается в корректной остановке. Именно для этого существуют команды kill, killall и тесно связанная с ними pkill.
В этом руководстве разберём, как эти команды работают, чем отличаются друг от друга, какие сигналы используют и в каких ситуациях применять каждую из них.
Сигналы Linux: основа управления процессами
Прежде чем завершать процессы, важно понять две вещи.
PID (Process ID) — уникальный числовой идентификатор, который ядро присваивает каждому запущенному процессу. Именно по PID команда kill находит нужный процесс.
Сигналы — механизм межпроцессного взаимодействия в Unix/Linux. Когда вы вызываете kill, вы не «убиваете» процесс напрямую — вы просите ядро отправить процессу определённый сигнал. Процесс может этот сигнал обработать или проигнорировать.
Как узнать PID процесса
Перед использованием kill нужно выяснить PID. Есть несколько способов.
# Показать все процессы текущего пользователя
ps aux | grep nginx
# Более точный поиск (исключает саму команду grep из результатов)
ps aux | grep '[n]ginx'
# Быстрый способ — утилита pgrep
pgrep nginx # выведет только PID
pgrep -a nginx # выведет PID и полную командную строку
pgrep -u www-data # процессы конкретного пользователя
# Интерактивные мониторы
top
htop
Пример вывода ps aux | grep nginx:
root 1234 0.0 0.1 4528 1034 ? Ss 10:00 0:00 nginx: master process
www-data 1235 0.0 0.3 4988 3012 ? S 10:00 0:05 nginx: worker process
www-data 1236 0.0 0.3 4988 2984 ? S 10:00 0:04 nginx: worker process
Здесь 1234, 1235, 1236 — это PID.
Какие бывают сигналы и зачем они нужны
Сигналов в Linux несколько десятков, но в повседневной работе используются в основном следующие.
| Номер | Имя сигнала | Описание | Можно перехватить? |
|---|---|---|---|
| 1 | SIGHUP | Перезагрузка конфига / завершение. Часто используется для перечитывания конфигурации без остановки | Да |
| 2 | SIGINT | Прерывание (аналог Ctrl+C в терминале) | Да |
| 9 | SIGKILL | Принудительное уничтожение процесса ядром | Нет |
| 15 | SIGTERM | Вежливая просьба завершиться (сигнал по умолчанию) | Да |
| 18 | SIGCONT | Возобновить остановленный процесс | Да |
| 19 | SIGSTOP | Принудительная приостановка ядром | Нет |
| 20 | SIGTSTP | Приостановка из терминала (аналог Ctrl+Z) | Да |
Полный список сигналов можно посмотреть командой:
kill -l
SIGTERM vs SIGKILL: принципиальная разница
Это самый важный момент в управлении процессами.
SIGTERM (15) — корректное завершение. Процесс получает сигнал и может:
-
сохранить данные на диск,
-
закрыть сетевые соединения,
-
удалить временные файлы,
-
освободить ресурсы,
-
завершить дочерние процессы.
SIGKILL (9) — принудительное уничтожение. Сигнал обрабатывается ядром, а не процессом. Процесс не получает никакого шанса на корректное завершение. Данные могут быть потеряны, временные файлы останутся, блокировки не снимутся.
Правило: всегда начинайте с SIGTERM. Используйте SIGKILL только когда процесс не реагирует на SIGTERM.
Команда kill
Синтаксис: kill [опции] [-сигнал] PID [PID...]
Команда kill отправляет сигнал процессу по его PID.
Основные примеры
Здесь 1234 — заглушка для PID.
# Отправить SIGTERM (сигнал по умолчанию) — корректное завершение
kill 1234
# Эквивалентные записи для SIGTERM
kill -15 1234
kill -SIGTERM 1234
kill -TERM 1234
kill -s TERM 1234
# Принудительное завершение (SIGKILL)
kill -9 1234
kill -SIGKILL 1234
kill -KILL 1234
# Перечитать конфигурацию (SIGHUP)
kill -1 1234
kill -HUP 1234
# Завершить несколько процессов одной командой
kill 1234 1235 1236
# Принудительно завершить несколько процессов
kill -9 1234 1235 1236
Практические сценарии
Сценарий 1: Корректная остановка веб-сервера
# Находим PID мастер-процесса nginx
pgrep -f "nginx: master"
# Допустим, вернулось 1234
# Отправляем SIGTERM
kill 1234
# Проверяем, завершился ли процесс
ps -p 1234
# Если процесс всё ещё существует, ждём несколько секунд и проверяем снова
sleep 5 && ps -p 1234
# Если всё ещё висит — принудительное завершение
kill -9 1234
Сценарий 2: Перезагрузка конфигурации без остановки
Многие демоны поддерживают SIGHUP для перечитывания конфига.
# Перечитать конфигурацию sshd
kill -HUP $(pgrep -x sshd)
# Перечитать конфигурацию nginx (nginx поддерживает это нативно)
kill -HUP $(cat /var/run/nginx.pid)
Сценарий 3: Завершение всех процессов пользователя
# Узнать все PID пользователя developer
pgrep -u developer
# Завершить все процессы пользователя
kill $(pgrep -u developer)
Завершение фоновых задач текущей сессии
kill в bash умеет работать со спецификаторами задач (job specs):
# Запустить процесс в фоне
sleep 300 &
# [1] 5678
# Посмотреть фоновые задачи
jobs
# [1]+ Running sleep 300 &
# Завершить по номеру задачи
kill %1
# Завершить по имени команды (если одна такая задача)
kill %sleep
Команда killall
Синтаксис: killall [опции] [-сигнал] имя_процесса [имя_процесса...]
Главное отличие от kill: команда killall принимает имя процесса, а не PID. Она находит все процессы с этим именем и отправляет сигнал каждому из них.
Внимание: на некоторых Unix-системах (Solaris, AIX) команда killall без аргументов завершает все процессы в системе. В Linux (пакет psmisc) она работает безопасно — требует указания имени. Но будьте осторожны при работе на не-Linux системах.
Основные примеры
# Завершить все процессы с именем "firefox"
killall firefox
# Принудительное завершение
killall -9 firefox
killall -KILL firefox
# Завершить процессы конкретного пользователя
killall -u www-data nginx
# Интерактивный режим — запрашивает подтверждение для каждого процесса
killall -i python3
# Показать, что было бы завершено, но не завершать (verbose)
killall -v firefox
# Подождать завершения всех процессов (команда блокируется)
killall -w firefox
# Завершить процессы младше 10 минут
killall -y 10m firefox
# Завершить процессы старше 1 часа
killall -o 1h firefox
Полезные флаги killall
| Флаг | Описание |
|---|---|
| -e | Точное совпадение имени (по умолчанию сравниваются только первые 15 символов) |
| -i | Интерактивный режим — спрашивает подтверждение |
| -I | Поиск имени без учёта регистра |
| -r | Интерпретировать имя как регулярное выражение |
| -u пользователь | Завершить только процессы указанного пользователя |
| -w | Дождаться завершения всех процессов |
| -v | Подробный вывод |
| -q | Тихий режим (не жаловаться, если процесс не найден) |
| -y время | Только процессы младше указанного времени |
| -o время | Только процессы старше указанного времени |
Практические сценарии
Сценарий 1: Зависший браузер
# Сначала попробовать корректное завершение
killall firefox
# Подождать 5 секунд
sleep 5
# Если не помогло — принудительно
killall -9 firefox
Сценарий 2: Остановка всех скриптов Python определённого пользователя
killall -u developer python3
Сценарий 3: Использование регулярных выражений
# Завершить все процессы, имя которых начинается на "worker"
killall -r '^worker'
Сценарий 4: Безопасное завершение с подтверждением
killall -i -v java
# Сигнал SIGTERM отправлен java (PID 2345)? [y/N] y
# Сигнал SIGTERM отправлен java (PID 2346)? [y/N] n
Команда pkill
pkill — это промежуточный вариант между kill и killall. Она ищет процессы по шаблону (как pgrep) и отправляет им сигнал.
Синтаксис: pkill [опции] [-сигнал] шаблон
Ключевое преимущество pkill
В отличие от killall, которая ищет по точному имени процесса, pkill использует регулярные выражения (POSIX regex), что позволяет искать по подстроке, шаблону или сложным выражениям, а с флагом -f — по всей командной строке.
# killall требует точного имени
killall nginx # ищет процессы с именем ровно "nginx"
# pkill ищет по подстроке
pkill ngin # найдёт "nginx", "nginx-debug" и т.д.
# Поиск по полной командной строке — самая мощная возможность
pkill -f "python3 /opt/myapp/worker.py"
# Без -f совпадение проверяется только по имени исполняемого файла (python3)
Основные примеры
# Завершить все процессы, в имени которых есть "http"
pkill http
# Принудительное завершение
pkill -9 http
# По полной командной строке
pkill -f "java -jar myapp.jar"
# Процессы конкретного пользователя
pkill -u www-data
# Комбинация: процессы пользователя, содержащие "worker"
pkill -u deploy -f worker
# Отправить SIGHUP для перечитывания конфига
pkill -HUP nginx
# Завершить процессы, привязанные к конкретному терминалу
pkill -t pts/2
# Завершить самый новый процесс с данным именем
pkill -n firefox
# Завершить самый старый процесс с данным именем
pkill -o firefox
Полезные опции pkill
| Опция | Описание |
|---|---|
| -f | Сопоставлять шаблон с полной командной строкой, а не только с именем процесса |
| -u пользователь | Только процессы данного пользователя (effective UID) |
| -U пользователь | Только процессы данного пользователя (real UID) |
| -t терминал | Только процессы на данном терминале |
| -P ppid | Только процессы с данным родительским PID |
| -g группа | Только процессы данной группы процессов |
| -n | Только самый новый (последний запущенный) процесс |
| -o | Только самый старый процесс |
| -x | Точное совпадение имени (как killall) |
Частые ошибки и подводные камни
1. Использование SIGKILL как первого средства
# НЕПРАВИЛЬНО — первое действие:
kill -9 <PID>
# ПРАВИЛЬНО — сначала SIGTERM, потом ожидание, потом SIGKILL:
kill <PID>
sleep 5
kill -9 <PID> # только если процесс не завершился
SIGKILL не даёт процессу возможности освободить ресурсы. Это может привести к повреждению данных, утечке разделяемой памяти, неудалённым lock-файлам.
2. Гонка PID (PID reuse)
Между моментом, когда вы узнали PID, и моментом, когда вы вызвали kill, процесс мог завершиться, а его PID мог быть переназначен другому процессу.
# Потенциально опасно в скриптах:
PID=$(pgrep myapp)
# ... прошло время ...
kill $PID # этот PID мог уже принадлежать другому процессу!
# Безопаснее использовать pkill/killall — они проверяют имя атомарно:
pkill myapp
3. Путаница killall на разных Unix-системах
# На Linux (psmisc) — завершает процессы по имени:
killall nginx # безопасно
# На Solaris/AIX — killall без аргументов завершает ВСЕ процессы!
# Никогда не запускайте killall без аргументов на незнакомой системе
4. Забытый минус перед номером сигнала
# НЕПРАВИЛЬНО — попытка завершить процессы 9 и 1234:
kill 9 1234
# ПРАВИЛЬНО — отправить сигнал 9 процессу 1234:
kill -9 1234
5. Процесс в состоянии D (Uninterruptible Sleep)
Процессы в состоянии D ожидают завершения операции ввода-вывода на уровне ядра. Даже SIGKILL не может их завершить — ядро доставит сигнал только после завершения операции ввода-вывода. Это часто встречается при проблемах с NFS или дисковыми устройствами.
# Найти процессы в состоянии D
ps -eo pid,stat,comm | awk '$2 ~ /D/'
# Решение — не kill, а устранение причины:
# отмонтировать зависший NFS, перезагрузить систему и т.д.
6. Права доступа
Обычный пользователь может отправлять сигналы только своим процессам. Для завершения чужих процессов нужны привилегии root.
# Ошибка: недостаточно прав
$ kill 1 # PID 1 — это init/systemd
bash: kill: (1) - Operation not permitted
# Решение:
sudo kill 1234
sudo killall nginx
sudo pkill -u otheruser
Заключение
Управление процессами — базовый навык системного администратора Linux. Подведём итог.
-
kill— точный инструмент. Используйте, когда знаете PID и хотите воздействовать на конкретный процесс. -
killall— удобен для завершения всех экземпляров программы по точному имени. -
pkill— самый гибкий вариант: поиск по подстроке, командной строке, пользователю, терминалу.
Всегда начинайте с SIGTERM, давайте процессу время на корректное завершение и прибегайте к SIGKILL только в крайнем случае. Этот подход сохранит целостность данных и убережёт от трудноуловимых проблем в продакшене.