Чи можна запускати cronjob кожні три дні? А може 10 разів / місяць.
Чи можна запускати cronjob кожні три дні? А може 10 разів / місяць.
Відповіді:
Запускайте його кожні три дні ...
0 0 */3 * *
Як щодо цього?
Якщо ви хочете, щоб він працював у певні дні місяця, наприклад, 1-й, 4-й, 7-й тощо ..., тоді у скрипті ви можете просто мати умовний текст, який перевіряє поточний день місяця.
if (((date('j') - 1) % 3))
exit();
або, як зазначає @mario, ви можете використовувати дату ('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
...
Згідно з цією статтею , вам потрібно додати деяку модульну математику до виконуваної команди, щоб отримати TRUE "кожні N днів". Наприклад:
0 0 * * * bash -c '(( $(date +\%s) / 86400 \% 3 == 0 )) && runmyjob.sh
У цьому прикладі завдання буде перевірятися щодня о 00: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 Epoch.