Назад | Перейти на главную страницу

Если условие истинно, отложите задание cron на 5 минут.

У меня есть сценарий, который запускается каждую минуту. Но в упомянутом сценарии, если условие выполняется, сценарий должен спать 5 минут. Как это могло повлиять на crontab? Будет ли скрипт находиться в спящем режиме в течение 5 минут или он будет запускаться снова, как это установлено в crontab, каждые 1 минуту?

У вас есть два варианта получить это. Обычно cron не имеет значения, работает ли предыдущий экземпляр задания.

Опция 1:

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

# if the file exists (`-e`) end the script:
[ -e "/var/lock/myscript.pid" ] && exit

# if not create the file:
touch /var/lock/myscript.pid

...
# do whatever the script does.
# if condition
sleep 300 # wait 5 min
...

# remove the file when the script finishes:
rm /var/lock/myscript.pid

Вариант 2:

Для этого также есть утилита. Это называется run-one. На странице руководства:

run-one - запускать по одному экземпляру некоторой команды и уникальный набор аргументов (полезно для cronjobs, например)

Тогда cronjob мог бы выглядеть так:

* * * * *   /usr/bin/run-one /path/to/myscript

Я сделал то же самое - приостановил скрипт, если что-то случилось, но я не запускал его из cron. Вместо этого у меня был сценарий оболочки, который постоянно перезапускался. В моем случае я проверил среднюю нагрузку и сделал паузу на минуту, если она была «слишком высокой». Все было в порядке, я делал то, что мне нужно было, а потом делал паузу на гораздо меньшее время.

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

#!/bin/bash

i_should_sleep() {
  if [ *condition* ]
  then
    return 0
  else
    return 1
  fi
}

if i_should_sleep; then
    sleep 300
    exec $0 $@
fi

nice COMMAND # run the action we really want to do

sleep 60  # or less than a minute, to run more often

exec $0 $@

Чтобы запустить его, вы должны создать задание Upstart или init.d или что-то подобное.

С crontab вы не можете этого сделать, но вы можете сделать это с небольшим расширением вашего скрипта. Я думаю о следующем псевдокоде:

#!/bin/bash
if ...temporary_file_exists
then
  if ...tmp_is_older_as_5_minute...
  then
     delete tmp
  else
     exit
  fi
fi

...
if "${condition}"
then
  touch $temporary_file
  exit
fi

...normal behavior of your script...

Что оно делает? Основная проблема скриптов cron в том, что вы не можете легко иметь постоянную память между их запусками. Вы должны делать это всегда специальными методами. В мире сценариев unix временные файлы являются очень распространенным решением для этого, и вы используете существование (и время изменения) временного файла, чтобы узнать, какова реальная ситуация.