{"id":893,"date":"2012-12-16T10:00:16","date_gmt":"2012-12-16T09:00:16","guid":{"rendered":"http:\/\/www.butschek.de\/?p=893"},"modified":"2012-12-16T10:00:53","modified_gmt":"2012-12-16T09:00:53","slug":"cron-last-friday","status":"publish","type":"post","link":"https:\/\/www.butschek.de\/2012\/12\/16\/cron-last-friday\/","title":{"rendered":"Cron: Letzter Freitag im Monat"},"content":{"rendered":"
Viele regelm\u00e4\u00dfig Aufgaben erledigen Admins mit Script, die per Cron gestartet werden. Solange sich das Zeitmuster im Format von Cron eingeben l\u00e4\u00dft, ist das alles kein Problem.<\/p>\n
Aber was, wenn ein Script z.B. am letzten Freitag im Monat gestartet werden soll? Das l\u00e4\u00dft sich in diesem Muster nicht darstellen. Es gibt aber ein paar einfache Tricks, die in Kombination zum Ziel dieser Aufgabe f\u00fchren.<\/p>\n
Mehrere Kommandos lassen sich mit && verkn\u00fcpfen. Die Shell f\u00fchrt dabei das zweite Kommando nur aus, wenn das erste Kommando erfolgreich war (Exitcode 0):<\/p>\n
\/usr\/local\/daten_einsammeln.sh && \/usr\/local\/daten_verarbeiten.sh<\/pre>\nSomit kann man die Ausf\u00fchrung des zweiten Scripts (Verarbeiten der Daten) vom Erfolg des ersten Scripts (Sammeln der Daten) abh\u00e4ngig machen.<\/p>\n
Trick 2: Abfragen ohne if mit [[ und ]]<\/h2>\n
Man kann mit [[ und ]] Bedingungen erstellen, ohne ‚if‘ einzusetzen. Ist die Bedingung erf\u00fcllt, wird Exitcode 0 zur\u00fcckgemeldet. In Kombination mit Trick 1 l\u00e4\u00dft sich so eine bedingte Ausf\u00fchrung realisieren, ohne mit if-then-fi arbeiten zu m\u00fcssen:<\/p>\n
[[ bedingung ]] && kommando<\/pre>\nTrick 3: Letzten Tag finden<\/h2>\n
Sucht man den letzten Freitag im Monat, so kann man das ganz einfach in eine Bedingung packen:<\/p>\n
Jetzt einfache mathematische Logik: Wenn der Monat in genau einer Woche anders ist als heute, dann ist der heutige Wochentag der letzte in diesem Monat vorkommende.<\/p>\n
Anders gesagt: Wenn wir in 7 Tagen in einem anderen Monat sind UND heute Freitag ist, dann ist heute der letzte Freitag im Monat.<\/p>\n
Wir starten einen Cronjob jeden Freitag und nutzen den Trick 2, um das Kommando nur auszuf\u00fchren, wenn eine Bedingung erf\u00fcllt ist. Die Bedingung ist aus Trick 3, wir pr\u00fcfen n\u00e4mlich, ob n\u00e4chsten Freitag schon ein neuer Monat ist. Das sieht so aus:<\/p>\n
[[ $(\/bin\/date -d '1 week' '+%m') -ne $(\/bin\/date '+%m') ]] && kommando<\/pre>\nSomit haben wir einen Cronjob, der jeden Freitag gestartet wird, aber das gew\u00fcnschte Kommando jeweils nur am letzten Freitag des Monats ausf\u00fchrt.<\/p>\n
Hier eine Beispieldatei (\/etc\/cron.d\/abrechnung), die Cron so akzeptieren wird:<\/p>\n
MAILTO=\"cronjobs@butschek.de\"\r\nPATH=\"\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:\/sbin:\/bin\"\r\n\r\n# +--------------------------------------------- Minute (0-59)\r\n# | +-------------------------------------- Stunde (0-24)\r\n# | | +------------------------------- Kalendertag (1-31)\r\n# | | | +------------------------ Monat (1-12)\r\n# | | | | +----------------- Wochentag (1-7 = Mo-So)\r\n# | | | | | +---------- Benutzer (z.B. root)\r\n# | | | | | | +--- Kommando (Pfad + Filename)\r\n# | | | | | | |\r\n\r\n# Abrechnung am Letzten Freitag im Monat starten\r\n 30 10 * * 5 root [[ $(\/bin\/date -d '1 week' '+%m') -ne $(\/bin\/date '+%m') ]] && \/usr\/local\/abrechnung\r\n\r\n# | | | | | | |\r\n# | | | | | | +--- Kommando (Pfad + Filename)\r\n# | | | | | +---------- Benutzer (z.B. root)\r\n# | | | | +----------------- Wochentag (1-7 = Mo-So\r\n# | | | +------------------------ Monat (1-12)\r\n# | | +------------------------------- Kalendertag (1-31)\r\n# | +-------------------------------------- Stunde (0-24)\r\n# +--------------------------------------------- Minute (0-59)<\/pre>\n","protected":false},"excerpt":{"rendered":"Viele regelm\u00e4\u00dfig Aufgaben erledigen Admins mit Script, die per Cron gestartet werden. Solange sich das Zeitmuster im Format von Cron eingeben l\u00e4\u00dft, ist das alles kein Problem. 0 9 * * * = Jeden Tag um 9 Uhr 30 14 * * 1-5 = Wochentags um 14:30 Uhr Aber was, wenn ein Script z.B. am […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,5],"tags":[12,96,19,45,66],"_links":{"self":[{"href":"https:\/\/www.butschek.de\/wp-json\/wp\/v2\/posts\/893"}],"collection":[{"href":"https:\/\/www.butschek.de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.butschek.de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.butschek.de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.butschek.de\/wp-json\/wp\/v2\/comments?post=893"}],"version-history":[{"count":18,"href":"https:\/\/www.butschek.de\/wp-json\/wp\/v2\/posts\/893\/revisions"}],"predecessor-version":[{"id":933,"href":"https:\/\/www.butschek.de\/wp-json\/wp\/v2\/posts\/893\/revisions\/933"}],"wp:attachment":[{"href":"https:\/\/www.butschek.de\/wp-json\/wp\/v2\/media?parent=893"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.butschek.de\/wp-json\/wp\/v2\/categories?post=893"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.butschek.de\/wp-json\/wp\/v2\/tags?post=893"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}