У меня есть сценарий, который запускается каждую минуту. Но в упомянутом сценарии, если условие выполняется, сценарий должен спать 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 временные файлы являются очень распространенным решением для этого, и вы используете существование (и время изменения) временного файла, чтобы узнать, какова реальная ситуация.