Führen Sie alle zwei Wochen ein Skript über cron aus

12

Ich habe ziemlich viel nachgeforscht, wie das geht, und ich sehe, dass es in cron keine direkte Möglichkeit gibt, einen Job zu erledigen, sagen wir, jeden zweiten Donnerstag.

Im Moment neige ich dazu, ein Skript zu erstellen , das nur jede Woche ausgeführt wird und eine "Flag" -Datei berührt, wenn es ausgeführt wird und die Datei bereits vorhanden ist, um die Datei zu entfernen (und nicht das auszuführen) zweiwöchentliche Aktion).

Meine Frage ist, gibt es einen eleganteren oder einfacheren Weg, um dieses Ziel eines Bash-Skripts von Aktionen zu erreichen, das alle zwei Wochen automatisch ausgeführt wird?

Vielen Dank!

dmkmills
quelle
1
Anstelle einer Flag-Datei können Sie auch ISO-Wochennummern verwenden. (ZB% V in der Freizeit.)
@ Roger: Ich nehme an, du meinst in einer Bedingung innerhalb des Skripts.
Bis auf weiteres angehalten.
@Dennis: Muss nicht sein (z. B. sehen, wie meine Antwort außerhalb des Skripts überprüft wird), aber meine Hauptsache ist, dass es viel einfacher ist und keinen Status im Dateisystem erfordert. Allerdings habe ich festgestellt, dass es einen ähnlichen Nachteil hat wie der Prüfungstag des Monats: Einige Jahre haben 53 Wochen und einige haben 52.

Antworten:

11
0 0 * * Thu bash -c '(($(date +\%s) / 86400 \% 14))' && your-script

Ich habe Bash benutzt, um zu rechnen, weil ich faul bin. schalte das auf was auch immer du willst. Ich nutze den 1. Januar 1970 als Donnerstag; Für andere Wochentage müssten Sie einen Offset anwenden. Cron muss den Prozentzeichen entkommen.

Schneller Check:

function check {
  when=$(date --date="$1 $(($RANDOM % 24)):$(($RANDOM % 60))" --utc)
  echo -n "$when: "
  (($(date +%s --date="$when") / 86400 % 14)) && echo run || echo skip
}

for start in "2010-12-02" "2011-12-01"; do
  for x in $(seq 0 12); do
    check "$start + $(($x * 7)) days"
  done
  echo
done

Hinweis: Ich habe zufällige Zeiten ausgewählt, um zu zeigen, dass dies funktioniert, wenn es am Donnerstag zu jeder Zeit ausgeführt wird. Außerdem habe ich Daten ausgewählt, die die Jahresgrenzen überschreiten und Monate mit jeweils 4 und 5 Donnerstagen enthalten.

Ausgabe:

Thu Dec  2 06:19:00 UTC 2010: run
Thu Dec  9 23:04:00 UTC 2010: skip
Thu Dec 16 05:37:00 UTC 2010: run
Thu Dec 23 12:49:00 UTC 2010: skip
Thu Dec 30 03:59:00 UTC 2010: run
Thu Jan  6 11:29:00 UTC 2011: skip
Thu Jan 13 13:23:00 UTC 2011: run
Thu Jan 20 20:33:00 UTC 2011: skip
Thu Jan 27 16:48:00 UTC 2011: run
Thu Feb  3 17:43:00 UTC 2011: skip
Thu Feb 10 05:49:00 UTC 2011: run
Thu Feb 17 08:46:00 UTC 2011: skip
Thu Feb 24 06:50:00 UTC 2011: run

Thu Dec  1 21:40:00 UTC 2011: run
Thu Dec  8 23:24:00 UTC 2011: skip
Thu Dec 15 22:27:00 UTC 2011: run
Thu Dec 22 02:47:00 UTC 2011: skip
Thu Dec 29 12:44:00 UTC 2011: run
Thu Jan  5 17:59:00 UTC 2012: skip
Thu Jan 12 18:31:00 UTC 2012: run
Thu Jan 19 04:51:00 UTC 2012: skip
Thu Jan 26 08:02:00 UTC 2012: run
Thu Feb  2 17:37:00 UTC 2012: skip
Thu Feb  9 14:08:00 UTC 2012: run
Thu Feb 16 18:50:00 UTC 2012: skip
Thu Feb 23 15:52:00 UTC 2012: run

quelle
2
Sekunden, seitdem die Epoche von Natur aus UTC ist, während cron in der Ortszeit ausgeführt wird. Wenn Ihre System-Zeitzone nicht UTC ist, führt dies zu Verwirrung. ("Warum läuft es nicht? Oh, es ist schon Freitag in UTC"). Die Existenz der Sommerzeit erschwert die
Umgehung dieses Problems
5

Eine Möglichkeit ist die Verwendung des atDienstprogramms unter Linux. Sie können dies am Ende Ihres Skripts einfügen:

at X + 2 weeks -f myscript

Dabei ist X die Zeit, zu der Sie Ihr Skript ausführen möchten. Zum Initialisieren rufen atSie einfach an, wann Sie es das erste Mal ausführen möchten, und mit der obigen Anweisung wird Ihr geplanter Anruf immer wieder erneuert.

gvkv
quelle
Wenn dies eine langfristige Lösung sein wird, würde ich nicht empfehlen, dies auszuführen, obwohl ich eine Funktion im Skript erstellen würde, die herausfinden würde, ob es ausgeführt werden muss
Paul
3

Wenn Sie anacronauf dem System verwenden können, werden die Dinge viel einfacher sein. Zur Verwendung anacronmuss es installiert sein und Sie müssen über Root-Zugriff verfügen. Es funktioniert nicht auf älteren Systemen (zB RHEL 5.x), die älteren Versionen von ancron laufen NUR beim Booten. Es funktioniert mit neueren Systemen (zB RHEL 6.x).

Mit anacronkönnen Jobs flexibler eingeplant werden, z. B. X-Job einmal pro Woche ausführen. Führt auch anacronJobs aus, wenn der Computer verfügbar wird, dh Sie müssen nicht berücksichtigen, wann das System hoch- oder runtergefahren ist.

Um ein Skript jede zweite Woche auszuführen, müssen Sie eine Zeile wie die folgende in die / etc / anacrontab einfügen:

14 5 myScript script.sh

Schauen Sie sich die Manpage für Details an.

memin
quelle
Verwenden anacronist eindeutig die sauberste Lösung, IMO (es sei denn, dies hat einige unerwünschte Konsequenzen für einige Leute).
28.
0

Ich bin mir nicht sicher, ob es eine elegantere Art gibt, die jede zweite Woche zu definieren, aber das könnte für Sie funktionieren.

00 06 1-7,15-21 * * test `date +\%a` = Thu && /path/to/script

Dadurch wird das Skript am ersten und dritten Donnerstag des Monats um 6:00 Uhr morgens gestartet.

pferieren
quelle
2
Das würde allerdings eine Woche überspringen, wenn es einen Monat mit 3 Donnerstagen gibt.
David Z
1
Gibt es einen Monat mit nur 3 Donnerstagen? Obwohl ich sehe, dass es eine Woche überspringt, wenn es 5 Donnerstag gibt. Es kann 1-7,15-21,29-31
nacheinander ablaufen,
1
Meinen Sie mit 3 Donnerstagen 3 Donnerstage, an denen das Skript ausgeführt wird, und nicht 3 Donnerstage insgesamt? Möglicherweise habe ich es beim ersten Mal falsch gelesen.
pferieren
0

Ich würde es jede Woche ausführen und das Skript überprüfen lassen, um festzustellen, ob die Wochennummer eine ungerade Zahl ist: Wenn ja, beenden.

Dies würde einige weitere Überlegungen erfordern, um von Dezember bis Januar zu funktionieren.

Vielleicht hat das Skript eine Flag-Datei "Letzte erfolgreiche Ausführung" gesetzt. Überprüfen Sie beim Starten des Skripts, ob die Flag-Datei vor 14 Tagen zuletzt geändert wurde.

Glenn Jackman
quelle