Cron Job alle drei Tage

93

Ist es möglich, alle drei Tage einen Cronjob durchzuführen ? Oder vielleicht 10 mal / Monat.

tmartin314
quelle
4
Ja, es ist möglich und dies gehört zu SuperUser.
Mit Anacron kann alle 3 Tage unabhängig von den Monatsgrenzen ausgeführt werden.
Ryanpattison

Antworten:

123

Führen Sie es alle drei Tage aus ...

0 0 */3 * *

Wie wär es damit?

Wenn Sie möchten, dass es an bestimmten Tagen des Monats ausgeführt wird, z. B. am 1., 4., 7. usw., können Sie in Ihrem Skript nur eine Bedingung festlegen, die den aktuellen Tag des Monats überprüft.

if (((date('j') - 1) % 3))
   exit();

oder, wie @mario betont, können Sie das Datum ('k') verwenden, um den Tag des Jahres abzurufen, anstatt es basierend auf dem Tag des Monats zu tun.

sberry
quelle
9
@whatshakin: Es hängt davon ab, wie genau "alle drei Tage" sein soll. Dies funktioniert an jedem Tag, der durch 3 teilbar ist. An Monatsgrenzen ist es nicht genau.
David
3
@whatshakin: Die Cronjob-Syntax ist sogar auf Wikipedia beschrieben: en.wikipedia.org/wiki/Cronjob
Felix Kling
4
Dies ist ein sehr hohes Ergebnis bei Google, und als solches wäre es besser, wenn die akzeptierte Antwort korrekt wäre, was dies nicht ist. Ich glaube, Tarecos Erklärung ist richtig.
Lynks
13
Die Antwort ist nicht korrekt, da keiner der Vorschläge den Job tatsächlich alle 3 Tage ausführt. 0 0 */3 * *bedeutet, dass am 1., 4., 7. usw. ausgeführt wird ( */3bedeutet 1-31/3Mittel 1,4,7...31), sodass die Lücke am Monatsende kleiner wird. (Es läuft 2 Tage hintereinander, wenn der Vormonat 31 Tage hatte.) Das date('j') % 3hat ein ähnliches Problem, da das Muster jedes Jahr neu
gestartet
8
Auch ich halte es für bedauerlich, dass dies als Antwort akzeptiert wurde. Ich habe wirklich alle N Tage gesucht, unabhängig von den Monatsgrenzen (Dinge wie Pflanzen kümmern sich nicht darum, an welchem ​​Tag des Monats sie ihr Wasser bekommen). Zumindest glaube ich, dass ich nach dem Lesen aller Kommentare festgestellt habe, dass der Cron-Timer diesen Wunsch nicht vollständig modelliert.
Travis Griggs
68
* * */3 * *  that says, every minute of every hour on every three days. 

0 0 */3 * *  says at 00:00 (midnight) every three days.
tareco
quelle
schätzen die Erklärung
pythonian29033
2
Dies wird normalerweise alle drei Tage
ausgelöst
23

Ich bin kein Cron-Spezialist, aber wie wäre es mit:

0 */72 * * *

Es wird alle 72 Stunden ohne Unterbrechung ausgeführt.

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

Fabio Nolasco
quelle
3
Dies ist genauer als die akzeptierte Lösung. Die akzeptierte Antwort schlägt fehl, wenn die Monate then at 2019-02-28 00:00:00 then at 2019-03-01 00:00:00
Akira Yamamoto
Wie berechnet man, wann dies geschehen wird?
Bruce Edge
2
Laut crontab.guru läuft dies jeden Tag. Wer hat Recht?
Velop
Der Wert in der Stundenspalte muss laut crontab.guru und man crontab zwischen 0 und 23 liegen .
Harperville
1
* / 72 ist effektiv dasselbe wie 0. Dies läuft jede Mitternacht.
Battey
18

Da cron "zustandslos" ist, kann es "Frequenzen" nicht genau ausdrücken, sondern nur "Muster", die es (anscheinend) kontinuierlich mit der aktuellen Zeit vergleicht.

Das Umformulieren Ihrer Frage macht dies offensichtlicher: "Ist es möglich, jeden Abend um 00:01 Uhr einen Cronjob auszuführen, außer Nächte zu überspringen, wenn er innerhalb von 2 Nächten ausgeführt wurde?" Wenn cron die aktuelle Zeit mit den Zeitmustern für Jobanfragen vergleicht, kann cron nicht wissen, ob Ihr Job in der Vergangenheit ausgeführt wurde.

Normalerweise müssen Sie dieses wiederkehrende Ereignis beenden und ein völlig neues neu starten. Dies zeigt die begrenzte Ausdruckskraft, wie selbst komplizierte Kalender-Apps sich wiederholende Muster darstellen. Und natürlich haben Kalender viele Status - jedes einzelne Ereignis kann unabhängig gelöscht oder neu geplant werden [in den meisten Kalender-Apps]).

Außerdem möchten Sie Ihre Arbeit wahrscheinlich jede dritte Nacht erledigen, wenn dies erfolgreich ist. Wenn die letzte fehlgeschlagen ist, versuchen Sie es sofort erneut, möglicherweise in der nächsten Nacht (warten Sie nicht noch 3 Tage) oder sogar früher, etwa eine Stunde später (aber hören Sie auf, es erneut zu versuchen bei der Ankunft am Morgen). Offensichtlich konnte cron unmöglich wissen, ob Ihr Job erfolgreich war, und das Muster kann auch keinen alternativen, häufigeren "Wiederholungs" -Zeitplan ausdrücken.

Wie auch immer - Sie können selbst tun, was Sie wollen. Schreiben Sie ein Skript und fordern Sie cron auf, es jeden Abend um 00:01 Uhr auszuführen. Dieses Skript könnte den Zeitstempel von etwas * überprüfen, das den "letzten Lauf" aufzeichnet, und wenn es> 3 Tage her ist **, den Job ausführen und den Zeitstempel "letzter Lauf" zurücksetzen.

(* Dieser zeitgestempelte Indikator ist ein Zustand des dauerhaften Zustands, den Sie manipulieren und untersuchen können, den Cron jedoch nicht.)

** Seien Sie vorsichtig mit der Zeitarithmetik, wenn Sie eine vom Menschen lesbare Uhrzeit verwenden - zweimal im Jahr, einige Tage haben 23 oder 25 Stunden an ihrem Tag, und 02: 00-02: 59 tritt zweimal an einem Tag auf oder nicht um alles. Verwenden Sie UTC, um dies zu vermeiden.

Jaime Guerrero
quelle
7
0 0 1-30/3 * *

Dies würde alle drei Tage ab dem 1. laufen. Hier sind die 20 geplanten Läufe -

  • 2015-06-01 00:00:00
  • 2015-06-04 00:00:00
  • 2015-06-07 00:00:00
  • 10.06.2015 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
Vishal
quelle
4
2015-07-31 00:00:00, 2015-08-01 00:00:00 ... OOPS nur 1 Tag zwischen den Läufen
Dziamid
4

Ich glaube nicht, dass Sie das haben, was Sie brauchen:

0 0 */3 * * ## <<< WARNING!!! CAUSES UNEVEN INTERVALS AT END OF MONTH!!

Leider stellt das * / 3 das Intervall an jedem n Tag des Monats und nicht an jedem n Tag ein . Siehe: Erklärung hier . Am Monatsende ist eine wiederkehrende Ausgabe garantiert.

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

Gemäß diesem Artikel müssen Sie dem ausgeführten Befehl etwas Modulo-Mathematik hinzufügen, um "alle N Tage" eine WAHRE zu erhalten. Beispielsweise:

0 0 * * *  bash -c '(( $(date +\%s) / 86400 \% 3 == 0 )) && runmyjob.sh

In diesem Beispiel wird der Job täglich um 12:00 Uhr überprüft, jedoch nur ausgeführt, wenn die Anzahl der Tage seit dem 01.01.1970 Modulo 3 0 beträgt.

Wenn Sie möchten, dass es alle 3 Tage ab einem bestimmten Datum angezeigt wird, verwenden Sie das folgende Format:

0 0 * * *  bash -c '(( $(date +\%s -d "2019-01-01") / 86400 \% 3 == 0 )) && runmyjob.sh
Brad Cozine
quelle
3

Wie wäre es mit:

00 00  *  *   * every 3 days && echo test

Wo everyist ein Skript:

#!/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

So läuft es jeden Tag.

Die Verwendung von */3Läufen am 3., 6., ... 27., 30. des Monats ist dann aber falsch, nachdem ein Monat einen 31. Tag hat. Das everySkript ist erst nach Jahresende falsch.

MattBlissett
quelle
2

Sie sollten die Grundlagen von lernen crontab.

Bearbeiten Sie den Cron per Befehl crontab -eund dann ⌃ (CTRL)+ Xdann Yund drücken Sie schließlich ENTER (return)auf dem Mac, um die Datei zu speichern. Sie können überprüfen, ob die neuen Crones nicht von installiert wurdencrontab -l

Eine Crontab-Datei enthält fünf Felder zur Angabe von Minuten, Stunden, des Monats des Monats, des Monats und des Wochentags, gefolgt von dem Befehl, der in diesem Intervall ausgeführt werden soll.

*     *     *   *    *   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)

* Im obigen Wertefeld sind alle zulässigen Werte wie in geschweiften Klammern für diese Spalte angegeben.

Hier habe ich einen ausführlichen Beitrag dazu geschrieben: Setup Cron in Unix

Ahmad Awais
quelle
1

Es wäre einfacher, wenn Sie es so konfigurieren würden, dass es nur am Montag und Donnerstag ausgeführt wird, was eine Pause von 3 und 4 Tagen bedeuten würde.

Andernfalls konfigurieren Sie es so, dass es täglich ausgeführt wird, aber lassen Sie Ihr PHP-Cron-Skript vorzeitig beenden mit:

if (! (date("z") % 3)) {
     exit;
}
Mario
quelle
0

Wenn Sie möchten, dass es an bestimmten Tagen des Monats ausgeführt wird, z. B. am 1., 4., 7. usw., können Sie in Ihrem Skript nur eine Bedingung festlegen, die den aktuellen Tag des Monats überprüft.

Ich dachte, alles, was Sie dafür brauchten, war anstelle von * / 3, was bedeutet, alle drei Tage, verwenden Sie 1/3, was bedeutet, dass alle drei Tage ab dem 1. des Monats beginnen. 7/3 würde also alle drei Tage ab dem 7. des Monats usw. bedeuten.

Colin Hilbert
quelle
0

0 0 * * * [ $(($((Datum +% - j- 1)) % 3)) == 0 ] && script

Holen Sie sich den Tag des Jahres von date, versetzt um 1, um bei 0 zu beginnen, und prüfen Sie, ob es Modulo drei ist.

Gerber
quelle
Wird das nicht Schluckauf sein, wenn es von einem Jahr ohne Sprung auf das nächste Jahr übergeht, seitdem ( 365-1 ) % 3 == 1aber ( 1 - 1 ) % 3 == 0? Ich würde denken, dass die bessere Berechnung auf der Anzahl der Tage seit der Unix-Epoche basiert.
kmoser