Ответ 1
Избегайте PID файлов, кротов или всего остального, которые пытаются оценить процессы, которые не являются их дочерними элементами.
Есть очень веская причина, почему в UNIX вы можете ТОЛЬКО ждать своих детей. Любой метод (разбор ps, pgrep, сохранение PID,...), который пытается обойти это, является ошибочным и имеет в нем зияющие отверстия. Просто скажите нет.
Вместо этого вам нужен процесс, который контролирует ваш процесс как родительский процесс. Что это значит? Это означает, что только процесс, который запускает ваш процесс, может надежно дождаться его завершения. В bash это абсолютно тривиально.
until myserver; do
echo "Server 'myserver' crashed with exit code $?. Respawning.." >&2
sleep 1
done
Вышеупомянутый фрагмент кода bash запускается myserver
в цикле until
. Первая строка начинается с myserver
и ждет ее завершения. Когда он закончится, until
проверяет свой статус выхода. Если статус выхода 0
, это означает, что он закончил изящно (это означает, что вы попросили его как-то закрыться, и он сделал это успешно). В этом случае мы не хотим его перезапускать (мы просто попросили его закрыть!). Если статус выхода не равен 0
, until
будет запускать тело цикла, которое выдает сообщение об ошибке на STDERR и перезапускает цикл (назад к строке 1) через 1 секунду.
Почему мы ждем секунду? Потому что, если что-то не так с порядком запуска myserver
, и он немедленно сработает, у вас будет очень интенсивный цикл постоянного перезапуска и сбоя в ваших руках. sleep 1
снимает напряжение с этого.
Теперь все, что вам нужно сделать, это запустить этот bash script (асинхронно, возможно), и он будет отслеживать myserver
и при необходимости перезапускать его. Если вы хотите запустить монитор при загрузке (перезагрузка сервера "выжить" ), вы можете запланировать его в своем пользовательском cron (1) с помощью правила @reboot
. Откройте свои правила cron с помощью crontab
:
crontab -e
Затем добавьте правило для запуска монитора script:
@reboot /usr/local/bin/myservermonitor
В качестве альтернативы; посмотрите на inittab (5) и /etc/inittab. Вы можете добавить туда строку, чтобы myserver
начинался с определенного уровня инициализации и автоматически обновлялся.
Изменить.
Позвольте мне добавить некоторую информацию о том, почему не использовать файлы PID. Хотя они очень популярны; они также очень ошибочны, и нет причин, по которым вы не просто сделаете это правильно.
Рассмотрим это:
-
Повторная утилизация ПИД (уничтожение неправильного процесса):
-
/etc/init.d/foo start
: startfoo
, напишитеfoo
PID на/var/run/foo.pid
- А позже:
foo
как-то умирает. - Позднее: любой случайный процесс, который запускается (назовем его
bar
), принимает случайный PID, представьте, что он принимаетfoo
старый PID. - Вы заметили, что
foo
ушел:/etc/init.d/foo/restart
читает/var/run/foo.pid
, проверяет, жив ли он, находитbar
, думает, что онfoo
, убивает его, запускает новыйfoo
.
-
-
Файлы PID остаются устаревшими. Для проверки того, является ли PID файл устаревшим, вам нужна чрезмерная (или, если нужно сказать, нетривиальная) логика, и любая такая логика снова уязвима для
1.
. -
Что делать, если вы даже не имеете права на запись или находитесь в среде только для чтения?
-
Это бессмысленное превышение; посмотрим, насколько прост в моем примере выше. Не нужно вообще усложнять это.
См. также: Являются ли PID файлы по-прежнему ошибочными, когда делаете это правильно?
Кстати; , даже хуже, чем файлы PID разбора ps
! Никогда не делайте этого.
-
ps
очень неспособен. Хотя вы находите его почти в каждой системе UNIX; его аргументы сильно различаются, если вы хотите нестандартный вывод. И стандартный вывод является ТОЛЬКО для потребления человеком, а не для сценария синтаксического анализа! - Разбор
ps
приводит к LOT ложных срабатываний. Возьмите примерps aux | grep PID
, и теперь представьте, что кто-то запускает процесс с номером где-то в качестве аргумента, который оказывается таким же, как PID, с которым вы смотрели на своего демона! Представьте, что два человека начинают сеанс X, и вы хотите, чтобы X убил вас. Это просто все плохо.
Если вы не хотите самостоятельно управлять процессом; есть отличные системы, которые будут работать в качестве монитора для ваших процессов. Посмотрите runit, например.