Ответ
Мягкое завершение — это отправка сигнала, который процесс может перехватить и корректно обработать (закрыть файлы, завершить транзакции, сохранить состояние). Основной сигнал для этого — SIGTERM (сигнал 15).
Стандартная последовательность действий:
-
Найти PID процесса:
ps aux | grep -i <process_name> # Или с помощью pgrep pgrep -f <process_name> -
Отправить SIGTERM:
kill -15 <PID> # Или по имени pkill -15 -f <process_name>После этого у процесса есть время на завершение (обычно это 30 секунд, но зависит от приложения).
-
Если SIGTERM не сработал — SIGINT (2): Это сигнал, аналогичный нажатию
Ctrl+Cв терминале.kill -2 <PID> -
Только в крайнем случае — SIGKILL (9): Сигнал
SIGKILLнельзя перехватить или проигнорировать. Я использую его, только если процесс не реагирует на мягкие сигналы, понимая риски (потеря данных, неконсистентное состояние).kill -9 <PID>
Практический пример для веб-сервера (Nginx):
# Graceful shutdown Nginx (завершит обработку текущих соединений)
sudo nginx -s quit
# Эта команда внутри отправляет SIGQUIT мастер-процессу
# Альтернативно, если знаем PID мастера:
sudo kill -QUIT $(cat /var/run/nginx.pid)
Важно для скриптов: В bash-скриптах, которые запускают долгоживущие процессы, я использую trap для обработки сигналов завершения и очистки.
#!/bin/bash
cleanup() {
echo "Получен сигнал завершения, останавливаем дочерние процессы..."
kill -TERM $child_pid 2>/dev/null
}
trap cleanup TERM INT
# Запуск основного процесса в фоне
./my_long_running_process &
child_pid=$!
# Ожидание завершения
wait $child_pid Ответ 18+ 🔞
А, ну это ж классика, ебать мои старые костыли! Сигналы в линуксе — это как общение с упрямым соседом. Сначала вежливо попросить, потом наорать, а в самом крайнем случае — вышибить дверь ногой.
Вот смотри, как правильно процесс уговаривать лечь и не дышать, чтобы он не накосячил.
Правильный подход, как с дамой:
-
Сначала ищем, с кем будем беседовать (PID):
ps aux | grep -i <process_name> # Или так, покороче pgrep -f <process_name> -
Вежливая просьба (SIGTERM, он же 15):
kill -15 <PID> # Или сразу по имени, если лень цифры вводить pkill -15 -f <process_name>Тут процессу говорят: «Дружище, закругляйся, но не спеши». У него есть время (ну, секунд 30 обычно) всё красиво прибрать — файлы закрыть, транзакции завершить. Если он адекватный, то сделает и сам выключится.
-
Если вежливость не работает — уже строже (SIGINT, он же 2): Это как нажать
Ctrl+Cв терминале. Более жёсткое, но ещё не смертельное указание.kill -2 <PID> -
Ну а если процесс совсем охренел и не реагирует — тогда уже пуля в лоб (SIGKILL, он же 9): Вот это уже не просьба, а приговор. Сигнал
SIGKILLнельзя перехватить или проигнорировать. Просто херак — и нет процесса. Но и последствия могут быть пиздец: данные не сохранились, файлы остались открытыми, состояние системы — как после буйной пьянки. Использую только в самом крайнем случае, когда терпения ноль ебать.kill -9 <PID>
Пример из жизни, с веб-сервером Nginx:
# Красиво просим Nginx завершиться (дождаться текущих запросов)
sudo nginx -s quit
# Внутри эта команда шлёт мастер-процессу сигнал SIGQUIT
# Или можно вручную, если знаем PID мастера:
sudo kill -QUIT $(cat /var/run/nginx.pid)
Важный лайфхак для скриптов: Если пишешь скрипт, который что-то запускает, сделай ему «совесть». Чтобы он, если его самого прервут, успел прибраться за своими детьми.
#!/bin/bash
cleanup() {
echo "Нас прерывают, чувак! Гасим всё, что запустили..."
kill -TERM $child_pid 2>/dev/null
}
# Вешаем ловушку на сигналы TERM и INT
trap cleanup TERM INT
# Запускаем наш долгий процесс в фоне
./my_long_running_process &
child_pid=$!
# И ждём, пока он не кончится
wait $child_pid
Вот так-то, ёпта. Сначала договаривайся, а уж потом ломай. Иначе можно такого наворотить, что потом неделю расхлёбывать.