Можно ли запускать cronjob каждые три дня? Или, может быть, 10 раз в месяц.
Можно ли запускать cronjob каждые три дня? Или, может быть, 10 раз в месяц.
Ответы:
Запускать каждые три дня ...
0 0 */3 * *
Как насчет этого?
Если вы хотите, чтобы он запускался в определенные дни месяца, например, 1-й, 4-й, 7-й и т. Д., Вы можете просто добавить в свой сценарий условие, которое проверяет текущий день месяца.
if (((date('j') - 1) % 3))
exit();
или, как указывает @mario, вы можете использовать date ('k'), чтобы получить день года, вместо того, чтобы делать это на основе дня месяца.
0 0 */3 * *
означает запуск 1-го, 4-го, 7-го и т. д. ( */3
означает 1-31/3
означает 1,4,7...31
), поэтому в конце месяца разрыв будет меньше. (Он будет работать 2 дня подряд, если в предыдущем месяце был 31 день.) date('j') % 3
Есть аналогичная проблема в том, что шаблон перезапускается каждый год, а в годах нет числа дней, кратного 3.
* * */3 * * that says, every minute of every hour on every three days.
0 0 */3 * * says at 00:00 (midnight) every three days.
Я не специалист по cron, но как насчет:
0 */72 * * *
Он будет работать каждые 72 часа без перерыва.
then at 2019-02-28 00:00:00 then at 2019-03-01 00:00:00
Поскольку cron «не имеет состояния», он не может точно выражать «частоты», а только «шаблоны», которые он (по-видимому) постоянно сопоставляет с текущим временем.
Если перефразировать ваш вопрос, это станет более очевидным: «Можно ли запускать cronjob в 00:01 каждую ночь, кроме пропуска ночей, если он выполнялся в течение 2 ночей?» Когда cron сравнивает текущее время с шаблонами времени запроса задания, cron никак не может узнать, выполнял ли он ваше задание в прошлом.
Обычно вам нужно прекратить это повторяющееся событие и перезапустить совершенно новое; это иллюстрирует ограниченную выразительность того, как даже сложные календарные приложения представляют повторяющиеся шаблоны. И, конечно же, у календарей много состояний - каждое отдельное событие может быть удалено или перенесено независимо [в большинстве приложений-календарей]).
Кроме того, в случае успеха вы, вероятно, захотите выполнять свою работу каждые 3 ночи. , но если последняя не удалась, попробовать снова немедленно, возможно, следующей ночью (не ждать еще 3 дня) или даже раньше, например, через час (но прекратите повторные попытки по прибытии утром). Ясно, что cron не может знать, успешно ли выполнена ваша работа, и шаблон не может также выражать альтернативный более частый график «повторов».
В любом случае - вы можете делать то, что хотите, сами. Напишите сценарий, скажите cron, чтобы он запускал его каждую ночь в 00:01. Этот сценарий может проверять метку времени чего-то *, что записывает «последний запуск», и, если это было> 3 дней назад **, выполнить задание и сбросить метку времени «последнего запуска».
(* этот индикатор с меткой времени представляет собой немного постоянного состояния, которым вы можете управлять и исследовать, но которое cron не может)
** будьте осторожны с арифметикой времени, если вы используете часы, удобочитаемые человеком - два раза в год, в некоторые дни в сутках 23 или 25 часов, а 02: 00-02: 59 встречается дважды за один день или не в все. Используйте UTC, чтобы этого избежать.
0 0 1-30/3 * *
Это будет выполняться каждые три дня, начиная с 1-го. Вот 20 запланированных запусков -
Не думаю, что у вас есть то, что вам нужно:
0 0 */3 * * ## <<< WARNING!!! CAUSES UNEVEN INTERVALS AT END OF MONTH!!
К сожалению, * / 3 устанавливает интервал в каждый n день месяца, а не каждые n дней . Смотрите: объяснение здесь . В конце месяца гарантирована повторная выдача.
1st at 2019-02-01 00:00:00
then at 2019-02-04 00:00:00 << 3 days, etc. OK
then at 2019-02-07 00:00:00
...
then at 2019-02-25 00:00:00
then at 2019-01-28 00:00:00
then at 2019-03-01 00:00:00 << 1 day WRONG
then at 2019-03-04 00:00:00
...
Согласно этой статье , вам нужно добавить математику по модулю к выполняемой команде, чтобы получать ИСТИНА «каждые N дней». Например:
0 0 * * * bash -c '(( $(date +\%s) / 86400 \% 3 == 0 )) && runmyjob.sh
В этом примере задание будет проверяться ежедневно в 12:00, но будет выполняться только тогда, когда количество дней с 01-01-1970 по модулю 3 равно 0.
Если вы хотите, чтобы это происходило каждые 3 дня с определенной даты, используйте следующий формат:
0 0 * * * bash -c '(( $(date +\%s -d "2019-01-01") / 86400 \% 3 == 0 )) && runmyjob.sh
Как насчет:
00 00 * * * every 3 days && echo test
Где every
скрипт:
#!/bin/sh
case $2 in
days)
expr `date +%j` % $1 = 0 > /dev/null
;;
weeks)
expr `date +%V` % $1 = 0 > /dev/null
;;
months)
expr `date +%m` % $1 = 0 > /dev/null
;;
esac
Так работает каждый день.
Использование */3
прогонов 3-го, 6-го, ... 27-го, 30-го числа месяца, но это неправильно, если в месяце есть 31-й день. every
Сценарий является неправильным только после того, как в конце года.
Вам следует изучить основы crontab
.
Отредактируйте cron с помощью команды, crontab -e
затем ⌃ (CTRL)+, Xзатем Yи, наконец, нажмите ENTER (return)Mac, чтобы сохранить файл. Вы можете проверить, установлены ли новые кроны, неcrontab -l
Файл crontab имеет пять полей для указания минут, часов, дня месяца, месяца и дня недели, за которыми следует команда, которая будет запускаться с этим интервалом.
* * * * * command to be executed
- - - - -
| | | | |
| | | | +----- day of week (0-6) (Sunday=0)
| | | +------- month (1-12)
| | +--------- day of month (1-31)
| +----------- hour (0-23)
+------------- min (0-59)
*
в поле значения выше означает все допустимые значения, указанные в фигурных скобках для этого столбца.
Здесь я написал об этом подробный пост: Настройка Cron в Unix
Если вы хотите, чтобы он запускался в определенные дни месяца, например, 1-й, 4-й, 7-й и т. Д., Вы можете просто добавить в свой сценарий условие, которое проверяет текущий день месяца.
Я думал, что все, что вам нужно для этого, было вместо * / 3, что означает каждые три дня, использовать 1/3, что означает каждые три дня, начиная с 1-го числа месяца. поэтому 7/3 будет означать каждые три дня, начиная с 7-го числа месяца и т. д.
0 0 * * * [ $(($((
дата +% - j- 1)) % 3)) == 0 ] && script
Получите день года date
, смещенный на 1, чтобы начать с 0, проверьте, является ли он по модулю три.
( 365-1 ) % 3 == 1
а ( 1 - 1 ) % 3 == 0
? Я думаю, что лучший расчет будет основан на количестве дней, прошедших с эпохи Unix.