Czy można uruchamiać cronjob co trzy dni? A może 10 razy w miesiącu.
Czy można uruchamiać cronjob co trzy dni? A może 10 razy w miesiącu.
Odpowiedzi:
Uruchom to co trzy dni ...
0 0 */3 * *
Co ty na to?
Jeśli chcesz, aby działał w określone dni miesiąca, na przykład 1, 4, 7 itd., Możesz po prostu mieć w swoim skrypcie warunek sprawdzający bieżący dzień miesiąca.
if (((date('j') - 1) % 3))
exit();
lub, jak wskazuje @mario, możesz użyć daty ('k'), aby uzyskać dzień roku, zamiast robić to na podstawie dnia miesiąca.
0 0 */3 * *oznacza, że biegnie 1, 4, 7 itd. ( */3oznacza 1-31/3oznacza 1,4,7...31), więc pod koniec miesiąca różnica będzie mniejsza. (Będzie działać przez 2 dni z rzędu, jeśli poprzedni miesiąc miał 31 dni.) date('j') % 3Ma podobny problem, ponieważ wzorzec jest uruchamiany ponownie co roku, a lata nie mają liczby dni podzielnych przez 3.
* * */3 * * that says, every minute of every hour on every three days.
0 0 */3 * * says at 00:00 (midnight) every three days.
Nie jestem specjalistą od cron, ale co powiesz na:
0 */72 * * *
Będzie uruchamiany co 72 godziny bez przerwy.
then at 2019-02-28 00:00:00 then at 2019-03-01 00:00:00
Ponieważ cron jest „bezstanowy”, nie może dokładnie wyrazić „częstotliwości”, a jedynie „wzorce”, które (najwyraźniej) w sposób ciągły dopasowuje do bieżącego czasu.
Ponowne sformułowanie pytania uczyni to bardziej oczywistym: „czy możliwe jest uruchamianie cronjob o 00:01 każdej nocy, z wyjątkiem pominiętych nocy, gdy trwało to w ciągu 2 nocy?” Kiedy cron porównuje bieżący czas z wzorcami czasu żądań zadań, nie ma możliwości, aby cron mógł dowiedzieć się, czy wykonywał Twoje zadanie w przeszłości.
Zwykle musisz zakończyć to powtarzające się wydarzenie i ponownie uruchomić zupełnie nowe; ilustruje to ograniczoną ekspresyjność tego, jak nawet skomplikowane aplikacje kalendarza przedstawiają powtarzające się wzorce. I oczywiście Kalendarze mają wiele stanów - każde wydarzenie można usunąć lub przełożyć niezależnie (w większości aplikacji kalendarza)).
Co więcej, prawdopodobnie będziesz chciał wykonywać swoją pracę co trzecią noc, jeśli się powiedzie , ale jeśli ostatnia się nie powiedzie, spróbuj ponownie natychmiast, być może następnej nocy (nie czekaj jeszcze 3 dni) lub nawet wcześniej, na przykład godzinę później (ale przestań próbować ponownie) po porannym przybyciu). Najwyraźniej cron nie mógł wiedzieć, czy twoje zadanie się powiodło, a wzorzec nie może również wyrazić alternatywnego, częstszego harmonogramu „ponownych prób”.
W KAŻDYM MIEJSCU-- Możesz sam robić, co chcesz. Napisz skrypt, powiedz cronowi, aby uruchamiał go co noc o 00:01. Ten skrypt może sprawdzić sygnaturę czasową czegoś *, co rejestruje „ostatnie uruchomienie”, a jeśli było to> 3 dni temu **, wykonać zadanie i zresetować znacznik czasu „ostatniego uruchomienia”.
(* ten znacznik czasu jest trochę utrwalonym stanem, którym możesz manipulować i badać, ale którego cron nie może)
** uważaj na arytmetykę czasu, jeśli używasz zegara czytelnego dla człowieka - dwa razy w roku, niektóre dni mają 23 lub 25 godzin dnia, a 02: 00-02: 59 występuje dwa razy w ciągu jednego dnia lub nie wszystko. Użyj UTC, aby tego uniknąć.
0 0 1-30/3 * *
Byłoby to uruchamiane co trzy dni, począwszy od 1. Oto 20 zaplanowanych biegów -
Myślę, że nie masz tego, czego potrzebujesz:
0 0 */3 * * ## <<< WARNING!!! CAUSES UNEVEN INTERVALS AT END OF MONTH!!
Niestety * / 3 ustawia interwał każdego n dnia miesiąca, a nie co n dni . Zobacz: wyjaśnienie tutaj . Pod koniec miesiąca gwarantowana jest cykliczna emisja.
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
...
Zgodnie z tym artykułem musisz dodać trochę matematyki modulo do wykonywanego polecenia, aby uzyskać PRAWDA „co N dni”. Na przykład:
0 0 * * * bash -c '(( $(date +\%s) / 86400 \% 3 == 0 )) && runmyjob.sh
W tym przykładzie zadanie będzie sprawdzane codziennie o godzinie 12:00, ale zostanie wykonane tylko wtedy, gdy liczba dni od 01-01-1970 modulo 3 wynosi 0.
Jeśli chcesz, aby było to co 3 dni od określonej daty, użyj następującego formatu:
0 0 * * * bash -c '(( $(date +\%s -d "2019-01-01") / 86400 \% 3 == 0 )) && runmyjob.sh
Co powiesz na:
00 00 * * * every 3 days && echo test
Gdzie everyjest skrypt:
#!/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
Więc działa codziennie.
Używanie */3uruchomień 3, 6, ... 27, 30 dnia miesiąca, ale wtedy jest błędne, gdy miesiąc ma 31 dzień. everySkrypt jest niewłaściwy dopiero po zakończeniu roku.
Powinieneś nauczyć się podstaw crontab.
Edycja cron przez polecenie crontab -e, a następnie ⌃ (CTRL)+ Xnastępnie Yi ostatecznie nacisnąć ENTER (return)na mac, aby zapisać plik. Możesz sprawdzić, czy nowe crony zostały zainstalowane lub nie przezcrontab -l
Plik crontab zawiera pięć pól do określania minut, godzin, dnia miesiąca, miesiąca i dnia tygodnia, po których następuje polecenie uruchamiane w tym przedziale.
* * * * * 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)
* w polu wartości powyżej oznacza wszystkie wartości prawne, jak w nawiasach klamrowych dla tej kolumny.
Tutaj napisałem szczegółowy post na ten temat: Skonfiguruj Cron w Uniksie
Byłoby prostsze, gdybyś skonfigurował go tak, aby działał tylko np. W poniedziałek i czwartek, co dałoby mu 3 i 4 dniową przerwę.
W przeciwnym razie skonfiguruj go tak, aby działał codziennie, ale spraw, aby skrypt php cron kończył się wcześniej za pomocą:
if (! (date("z") % 3)) {
exit;
}
Jeśli chcesz, aby działał w określone dni miesiąca, na przykład 1, 4, 7 itd., Możesz po prostu mieć w swoim skrypcie warunek sprawdzający bieżący dzień miesiąca.
Myślałem, że wszystko, czego potrzebujesz, to zamiast * / 3, co oznacza, że co trzy dni używaj 1/3, co oznacza co trzy dni, zaczynając od pierwszego dnia miesiąca. więc 7/3 oznaczałoby co trzy dni począwszy od 7 dnia miesiąca itd.
0 0 * * * [ $(($((data +% - j- 1)) % 3)) == 0 ] && script
Pobierz dzień roku od date, przesunięty o 1, aby rozpocząć od 0, sprawdź, czy jest to modulo trzy.
( 365-1 ) % 3 == 1ale od tego czasu ( 1 - 1 ) % 3 == 0? Myślę, że lepsze obliczenia byłyby oparte na liczbie dni, które upłynęły od Epoki Uniksa.