Предотвратите процесс убийства себя с помощью pkill
Я пишу процедуру остановки для службы запуска script:
do_stop()
{
rm -f $PIDFILE
pkill -f $DAEMON || return 1
return 0
}
Проблема в том, что pkill (то же самое с killall) также совпадает с процессом, представляющим сам script, и он в основном завершает себя. Как это исправить?
Ответы
Ответ 1
Вы можете явно отфильтровать текущий PID из результатов:
kill $(pgrep -f $DAEMON | grep -v ^$$\$)
Чтобы правильно использовать флаг -f
, обязательно укажите весь путь к демонам, а не только подстроку. Это предотвратит убийство script (и устранит необходимость выше grep
), а также из-за убийства всех других системных процессов, которые могут совместно использовать имя демона.
Ответ 2
pkill -f
принимает полномасштабное регулярное выражение. Поэтому вместо pkill -f $DAEMON
вы должны использовать:
pkill -f "^"$DAEMON
Чтобы убедиться, что только имя процесса начинается с данного имени демона, тогда только он убит.
Лучшим решением будет сохранение pid (Proces Id) процесса в файле при запуске процесса. И для остановки процесса просто прочитайте файл, чтобы получить идентификатор процесса, который нужно остановить/убить.
Ответ 3
Судя по вашему вопросу, вам не сложно использовать pgrep и pkill, так что вот некоторые другие варианты, которые обычно используются.
1) Используйте killproc
из /etc/init.d/functions
или /lib/lsb/init-functions
(который когда-либо подходит для вашего дистрибутива и версии Linux). Если вы пишете службу script, вы можете включить этот файл, если в качестве примера использовали одну из других служб.
Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]
Основное преимущество использования этого заключается в том, что он отправляет SIGTERM, ждет, будет ли процесс завершен и отправит SIGKILL только при необходимости.
2) Вы также можете использовать секретный соус killproc, который должен найти идентификаторы процессов для уничтожения с помощью pidof
, у которого есть опция -o
для исключения конкретного процесса. Аргументом для -o
может быть $$
, текущий идентификатор процесса или %PPID
, который является специальной переменной, которую pidof интерпретирует как вызывающий pidof script. Наконец, если демона является script, вам понадобится -x, поэтому вы пытаетесь убить script по имени, а не убить bash или python.
for pid in $(pidof -o %PPID -x progd); do
kill -TERM $pid
done
Вы можете увидеть пример этого в статье Bash: как проверить, работает ли ваш script.