Cron co trzy dni


94

Czy można uruchamiać cronjob co trzy dni? A może 10 razy w miesiącu.


4
Tak, jest to możliwe i należy to do SuperUser.

uruchamianie co 3 dni, niezależnie od granic miesiąca, można wykonać za pomocą anacron.
ryanpattison

Odpowiedzi:


129

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.


9
@whatshakin: Będzie to zależeć od tego, jak dokładne chcesz, aby „co trzy dni” były. To zadziała w każdym dniu, który można podzielić przez 3. W granicach miesiąca nie będzie dokładne.
David

3
@whatshakin: Składnia cronjob jest nawet opisana na Wikipedii: en.wikipedia.org/wiki/Cronjob
Felix Kling

4
To bardzo wysoki wynik w google i jako taki byłoby lepiej, gdyby przyjęta odpowiedź była prawidłowa, a tak nie jest. Uważam, że wyjaśnienie Tareco jest prawidłowe.
lynks

14
Odpowiedź jest nieprawidłowa, ponieważ żadna z sugestii nie uruchamia zadania co 3 dni. 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.
cjm

8
Ja również uważam za niefortunne, że to zostało przyjęte jako odpowiedź. Naprawdę szukałem każdego N dni, niezależnie od granic miesiąca (takie rzeczy jak rośliny nie obchodzą, w który dzień miesiąca dostają wodę). Przynajmniej wydaje mi się, że po przeczytaniu wszystkich komentarzy stwierdziłem, że sam zegar cron nie modeluje w pełni tego pragnienia.
Travis Griggs

70
* * */3 * *  that says, every minute of every hour on every three days. 

0 0 */3 * *  says at 00:00 (midnight) every three days.

doceniam wyjaśnienie
pythonian29033

2
To będzie
odpalane

24

Nie jestem specjalistą od cron, ale co powiesz na:

0 */72 * * *

Będzie uruchamiany co 72 godziny bez przerwy.

https://crontab.guru/#0_ / 72_ _ _


3
Jest to dokładniejsze niż przyjęte rozwiązanie. Przyjęta odpowiedź nie powiedzie się przy zmianie miesięcy:then at 2019-02-28 00:00:00 then at 2019-03-01 00:00:00
Akira Yamamoto,

Jak obliczyć, kiedy to nastąpi?
Bruce Edge

2
Według crontab.guru odbywa się to codziennie. Kto ma rację?
velop

1
Wartość w kolumnie godzin musi mieścić się w przedziale od 0 do 23 zgodnie z crontab.guru i man crontab .
harperville

1
* / 72 to faktycznie to samo, co 0. Odbywa się co północ.
battey

19

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ąć.


7
0 0 1-30/3 * *

Byłoby to uruchamiane co trzy dni, począwszy od 1. Oto 20 zaplanowanych biegów -

  • 2015-06-01 00:00:00
  • 2015-06-04 00:00:00
  • 2015-06-07 00:00:00
  • 2015-06-10 00:00:00
  • 2015-06-13 00:00:00
  • 2015-06-16 00:00:00
  • 2015-06-19 00:00:00
  • 2015-06-22 00:00:00
  • 2015-06-25 00:00:00
  • 2015-06-28 00:00:00
  • 2015-07-01 00:00:00
  • 2015-07-04 00:00:00
  • 2015-07-07 00:00:00
  • 2015-07-10 00:00:00
  • 2015-07-13 00:00:00
  • 2015-07-16 00:00:00
  • 2015-07-19 00:00:00
  • 2015-07-22 00:00:00
  • 2015-07-25 00:00:00
  • 2015-07-28 00:00:00

5
2015-07-31 00:00:00, 2015-08-01 00:00:00 ... OOPS tylko 1 dzień między
kursami

5

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

3

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.


3

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


1

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;
}

0

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 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.


Czy nie będzie to czkawka, gdy przewróci się z roku innego niż przestępny na rok następny, ( 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.
kmoser
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.