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. ( */3
oznacza 1-31/3
oznacza 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') % 3
Ma 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 every
jest 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 */3
uruchomień 3, 6, ... 27, 30 dnia miesiąca, ale wtedy jest błędne, gdy miesiąc ma 31 dzień. every
Skrypt 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 == 1
ale 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.