cron: запустить процесс, но только если он не запущен?


11

Могу ли я сказать cron запустить приложение, НО не запускать его, если процесс уже существует?

linux  cron 

Не могли бы вы уточнить, должно ли приложение не запускаться, если оно уже запущено или уже запущен другой процесс. Спасибо
Linker3000

Ответы:


23

самый простой способ, используйте pgrep

в crontab:

* * * * * pgrep processname > /dev/null || /path/to/processname -args0 -args1

Люблю простоту этого ответа. К вашему сведению, вы должны иметь возможность добавить флаг -f в pgrep, и затем вы можете проверить полное имя процесса, что полезно, если вы также хотите проверить аргументы процесса как часть вашего условия.
Крейг Сефтон

6
Нет, вы не можете использовать флаг -f с pgrep внутри cronjob. Причина в том, что вы будете сопоставлять сценарий оболочки, используемый для запуска самого cronjob.
CpnCrunch

При запуске процесса с графическим интерфейсом с помощью cron добавьте export DISPLAY=:0во избежание Could not connect to displayошибок. * * * * * export DISPLAY=:0 && pgrep processname > /dev/null || /path/to/processname -args0 -args1
Бенджам

9

Запустите скрипт, а не непосредственно программу. Есть много возможностей. Например :

MYPROG="myprog"
RESTART="myprog params"
PGREP="/usr/bin/pgrep"
# find myprog pid
$PGREP ${MYPROG}
# if not running
if [ $? -ne 0 ]
then
   $RESTART
fi

1
К вашему сведению - использование скалярных переменных для хранения списков аргументов считается плохой практикой. См. Mywiki.wooledge.org/BashFAQ/050 для примера случая, когда это терпит неудачу.
Чарльз Даффи

... Точно так же pgrep myprog; if [ $? -ne 0 ]; then ...было бы лучше написать какif ! pgrep myprog; then ...
Чарльз Даффи

... этот последний стиль не только более читабелен, но и менее подвержен ошибкам: легко непреднамеренно нарушить значение $?, например, путем добавления сообщений журнала или обработки ошибок между строками.
Чарльз Даффи

7

Этот сценарий не запустится снова, если предыдущий экземпляр еще не завершен. Если вы хотите что-то не запускать, если запущен другой конкретный процесс, смотрите скрипт harrymc.

DATE=`date +%c`;
ME=`basename "$0"`;
LCK="./${ME}.LCK";
exec 8>$LCK;

if flock -n -x 8; then
  echo ""
  echo "Starting your script..."
  echo ""

[PUT YOUR STUFF HERE]

  echo ""
  echo "Script started  $DATE";
  echo "Script finished `date +%c`";
else
  echo "Script NOT started - previous one still running at $DATE";
fi

3

Вы можете использовать файл блокировки в своем скрипте, но, пожалуйста, смотрите Управление процессами .

flock это одна утилита, которая может быть использована.


Неплохо! теперь rsync по этой медленной линии может занимать все необходимое время, срабатывая в течение 5 минут после */5 * * * * root flock /run/shm rsync -auhx --numeric-ids -e "ssh -T -c arcfour128 -o Compression=no -x" [source] [user]@[host]:[dest]
запуска

1

Это обычно обрабатывается самой программой, а не cron. Для этого есть два стандартных метода:

1) grepвывод, psчтобы увидеть, запущен ли уже процесс с таким именем

2) При запуске сначала проверьте наличие файла pid (идентификатор процесса), обычно по адресу /var/run/program_name.pid, и, если он существует, прочитайте pid из файла и проверьте, существует ли этот процесс еще; если это произойдет, откажитесь начать. Если файл pid не существует или pid в этом файле исчез, то создайте файл pid, запишите в него свой идентификатор процесса и продолжите обычный запуск.

Хотя технически возможно написать bash-каналы, которые будут выполнять любой из них непосредственно в вашем crontab, лучше добавить их в запускаемую программу (чтобы они применялись независимо от того, как она запускается) или написать скрипт-обертку для справиться с этим, как предложил Гарримк.


0

* * * * * pgrep -f "[p]attern" > /dev/null || /path/to/processname -args0 -args1

Я повторно использовал приведенный выше ответ с улучшением сопоставления с образцом. Параметр pgrep без f не соответствует шаблону процесса. Тем не менее, есть проблема с использованием опции f. С опцией f оболочка, порождающая cron, всегда совпадает и возвращает свой pid, поэтому процесс никогда не перезапускается.

Добавление шаблона [] вокруг одной из букв соответствует только процессу, и pid оболочки cron не возвращается.


0

Документы: https://www.timkay.com/solo/

solo - очень простой скрипт (10 строк), который не позволяет программе запускать более одной копии за раз. С помощью cron полезно убедиться, что задание не запускается до завершения предыдущего.

пример

* * * * * solo -port=3801 ./job.pl blah blah
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.