Запускать задание cron, только если оно еще не запущено - PullRequest
112 голосов
/ 02 марта 2010

Итак, я пытаюсь настроить работу cron как своего рода сторожевого пса для созданного мной демона.Если демон выходит из строя и дает сбой, я хочу, чтобы задание cron периодически перезапускало его ... Я не уверен, насколько это возможно, но я прочитал несколько руководств cron и не смог найти ничего, что могло бы сделать то, что яищу ...

Мой демон запускается из сценария оболочки, поэтому я просто ищу способ запустить задание cron ТОЛЬКО если предыдущий запуск этого задания еще не запущен.

Я нашел этот пост , который дал решение для того, что я пытаюсь сделать, используя блокировку файлов, но я не уверен, что есть лучший способ сделать это...

Спасибо за вашу помощь.

Ответы [ 15 ]

109 голосов
/ 03 марта 2010

Я делаю это для программы диспетчера очереди печати, которую я написал, это всего лишь сценарий оболочки:

#!/bin/sh
if ps -ef | grep -v grep | grep doctype.php ; then
        exit 0
else
        /home/user/bin/doctype.php >> /home/user/bin/spooler.log &
        #mailing program
        /home/user/bin/simplemail.php "Print spooler was not running...  Restarted." 
        exit 0
fi

Он запускается каждые две минуты и довольно эффективен. Мне пришло письмо со специальной информацией, если по какой-то причине процесс не запущен.

91 голосов
/ 29 октября 2015

Используйте flock. Это новое. Лучше.

Теперь вам не нужно писать код самостоятельно. Проверьте больше причин здесь: https://serverfault.com/a/82863

/usr/bin/flock -n /tmp/my.lockfile /usr/local/bin/my_script
58 голосов
/ 17 сентября 2011

Как уже говорили другие, написание и проверка PID-файла является хорошим решением. Вот моя реализация bash:

#!/bin/bash

mkdir -p "$HOME/tmp"
PIDFILE="$HOME/tmp/myprogram.pid"

if [ -e "${PIDFILE}" ] && (ps -u $(whoami) -opid= |
                           grep -P "^\s*$(cat ${PIDFILE})$" &> /dev/null); then
  echo "Already running."
  exit 99
fi

/path/to/myprogram > $HOME/tmp/myprogram.log &

echo $! > "${PIDFILE}"
chmod 644 "${PIDFILE}"
22 голосов
/ 02 марта 2010

Не пытайтесь делать это через cron. Пусть cron запустит скрипт, несмотря ни на что, и пусть скрипт решит, запущена ли программа, и запустите его при необходимости (обратите внимание, что для этого вы можете использовать Ruby или Python или ваш любимый язык сценариев)

18 голосов
/ 09 августа 2016

Удивительно, что никто не упомянул про run-one . Я решил мою проблему с этим.

 apt-get install run-one

затем добавьте run-one перед вашим скриптом crontab

*/20 * * * * * run-one python /script/to/run/awesome.py

Проверьте этот askubuntu SE ответ. Вы можете найти ссылку на подробную информацию там же.

10 голосов
/ 14 августа 2012

Вы также можете сделать это как однострочник прямо в вашем crontab:

* * * * * [ `ps -ef|grep -v grep|grep <command>` -eq 0 ] && <command>
5 голосов
/ 03 марта 2010

В качестве ответа на ответ Earlz вам необходим скрипт-обертка, который создает файл $ PID.running при его запуске и удаляет при его завершении. Скрипт-обёртка вызывает скрипт, который вы хотите запустить. Обертка необходима в случае сбоя целевого скрипта или ошибки, файл pid удаляется ..

4 голосов
/ 26 августа 2016

Когда я запускаю php-скрипты, я делаю это так:

Crontab:

* * * * * php /path/to/php/script.php &

Код php:

<?php
if (shell_exec('ps aux | grep ' . __FILE__ . ' | wc  -l') > 1) {
    exit('already running...');
}
// do stuff

Эта команда ищет в списке системных процессов текущее имя файла php если он существует, счетчик строк (wc -l) будет больше единицы, потому что сама команда поиска содержит имя файла

, поэтому, если вы запускаете php crons, добавьте приведенный выше код в начало вашего php-кода, и он запустится только один раз.

3 голосов
/ 20 октября 2014

С lockrun вам не нужно писать скрипт-обертку для вашей работы cron. http://www.unixwiz.net/tools/lockrun.html

3 голосов
/ 03 марта 2010

Я бы рекомендовал использовать существующий инструмент, такой как monit , он будет контролировать и автоматически перезапускать процессы. Больше информации доступно здесь . Он должен быть легко доступен в большинстве дистрибутивов.

...