Мне нужно начинать cronjob каждый день, но через час каждый день. То, что у меня пока работает, по большей части, кроме 1 дня в году:
0 0 * * * sleep $((3600 * (10#$(date +\%j) \% 24))) && /usr/local/bin/myprog
Если день года 365, задание начнется в 5:00, но на следующий день (не считая високосного года) будет день года, равный 1, поэтому задание начнется в 1:00. Как я могу избавиться от этого углового случая?
Ответы:
Моим предпочтительным решением было бы запускать работу каждый час, но сам скрипт проверял, пора ли ему запускаться или нет, и завершать работу, ничего не делая 24 раза из 25.
кронтаб:
в верхней части
myprog
:Если вы не хотите вносить какие-либо изменения в сам скрипт, вы можете также поставить проверку «время выполнения» в записи crontab, но это приводит к длинной неприглядной строке:
источник
date
возвращаемое ядром, было1ms
раньше времени, которое вы ожидали, что скрипт будет запущен, проверка выдаст неверный результат.ntpd
, он действительно старается только убить часы, а не прыгать, особенно во избежание такого рода проблем, но вы правы,ntpdate
иногда он (или ) может прыгать назад. Что касаетсяcron
просчета его задержки сна, я уверен, что это будет ошибкой! Тем не менее, точка отсчета принята, и обходной путь может заключаться в том, чтобы запланировать задание на 30 минут позже часа, что с меньшей вероятностью вызовет проблему ... Или добавьте ± 1800 в арифметическом выражении перед принятием мода reamainder 3600.Если в вашей системе установлен systemd, вы можете использовать для этого события таймеров. Просто определите новый сервис , который должен содержать команду / задачу, которую вы хотите выполнить, а затем создайте событие таймера с
OnUnitActiveSec
опцией:Используйте одно и то же имя для файлов, за исключением того, что вместо
.service
вы используете.timer
.синтезируя:
job.service
в/etc/systemd/system/
каталоге.systemctl status job.service
.job.timer
in/etc/systemd/system/
.Заполните его необходимой информацией:
systemctl list-timers
источник
Если вы не возражаете против использования чего-то другого, кроме cronjobs, я бы предложил менее известную утилиту
at
. Просто напишите скрипт-обертку, который запланирует запуск через 25 часов, а затем вызовет вашу программу. Это кажется самым чистым решением.Например, вы можете написать это в ~ / script.sh:
А потом просто беги
bash ~/script.sh
один раз.Спасибо @HalosGhost за идею планирования работы один раз в 25 часов.
источник
at
для этой цели: (1) если задание не может быть выполнено правильно хотя бы один раз, оно также, вероятно, не сможет перепланировать себя, а затем не только следующее выполнение, но все будущие выполнения будут эффективно отменены, пока человек не заметит, и (2) поскольку выполнение задания занимает ненулевое время, используя наивноеnow + 25 hours
средство, оно будет выполняться на несколько секунд (или больше) позже каждый раз, и если это отставание будет накапливаться с течением времени, то есть в конечном итоге оно будет выполнено с совершенно неправильным время.at
ограничено минутами и запускает все задания в [время]: 00.at
работы первым делом в сценарии at позволяет избежать этих проблем. Несмотря на это, если происходит ошибка, то вся цепочка разрывается, что может быть или не быть желательным: если сценарий использования «запускать только тогда, когда он работает», не перезапуск является отличной возможностью. Но если вариант использования «всегда запущен, даже если последний не удался», тоat
это не тот инструмент.