Cron erlaubte das Sonderzeichen "L" für "Letzter Tag des Monats" auf Debian

8

Ich würde gerne wissen, ob Leines der erlaubten Sonderzeichen in Debians Cron-Implementierung ist. Ich versuche, einen Cron einzurichten, der am letzten Tag eines jeden Monats ausgeführt wird.

Aus dem Cron-Eintrag auf Wikipedia :

'L' steht für "last". Bei Verwendung im Feld Wochentag können Sie Konstrukte wie "den letzten Freitag" ("5L") eines bestimmten Monats angeben. Im Feld Tag des Monats wird der letzte Tag des Monats angegeben.

Hinweis: L ist ein nicht standardmäßiges Zeichen und existiert nur in einigen Cron-Implementierungen (Quartz Java Scheduler).

Wenn nicht, wie würden Sie vorgehen, um einen Cron so einzustellen, dass er am letzten Tag eines jeden Monats ausgeführt wird? Würden Sie 3 verschiedene Einträge wie diese Lösung für den Stackoverflow empfehlen ?

Jeff
quelle

Antworten:

6

Cron-Einträge auf Debian werden in der crontab-Manpage ( man 5 crontab) beschrieben. Debian benutzt Vixies Cron und seine Manpage sagt:

   The crontab syntax does not make it possible  to  define  all  possible
   periods  one could image off. For example, it is not straightforward to
   define the last weekday of a month. If a task needs to be run in a spe-
   cific  period of time that cannot be defined in the crontab syntaxs the
   best approach would be to have the program itself check  the  date  and
   time  information and continue execution only if the period matches the
   desired one.

   If the program itself cannot do the checks then a wrapper script  would
   be required. Useful tools that could be used for date analysis are ncal
   or calendar For example, to run a program the last  Saturday  of  every
   month you could use the following wrapper code:

   0 4 * * Sat   [ "$(date +%e)" = "`ncal | grep $(date +%a | sed  -e 's/.$//') 
     | sed -e 's/^.*\s\([0-9]\+\)\s*$/\1/'`" ] && echo "Last Saturday" &&
     program_to_run

Arbeiten Sie also in diese Richtung:

   0 0 * * * perl -MTime::Local -e 
       'exit 1 if (((localtime(time()+60*60*24))[3]) < 2);' || program_to_run
Drav Sloan
quelle
4

Ich habe das noch nie Lbei einer Linux-Cron-Implementierung gesehen.

Um einen Job am letzten Tag des Monats auszuführen, führen Sie ihn an einer Obermenge der tatsächlichen Tage aus und überprüfen Sie das Datum des nächsten Tages. Mit GNU datekönnen Sie date -d tomorrowdas Datum des nächsten Tages anzeigen. Überprüfen Sie daher, ob es noch im selben Monat liegt. Geben Sie eine Tageszeit an, die nicht den frühen Morgenstunden entspricht (in den Beispielen 12:00 Uhr / 12:00 Uhr), um Probleme an einigen Orten an einem Tag zu vermeiden, an dem die Sommerzeit beginnt oder endet. Denken Sie daran, dass dies etwas %Besonderes in einem Crontab ist und durch einen Backslash geschützt werden muss.

42 1 28-31 * * if [ "$(date -d 'today 12:00' +\%m)" != "$(date -d 'tomorrow 12:00' +\%m)" ]; then last_day_of_month_job; fi

Sie können dieselbe Technik für das letzte Auftreten eines bestimmten Wochentags im Monat anwenden. Führen Sie den Job wöchentlich aus und lassen Sie ihn nur auslösen, wenn das nächste Auftreten in einem anderen Monat liegt.

42 1 * * 3 if [ "$(date -d 'today 12:00' +\%m)" != "$(date -d 'now + 7 days 12:00' +\%m)" ]; then last_wednesday_of_month_job; fi
Gilles 'SO - hör auf böse zu sein'
quelle
2

Es ist etwas umständlich, dies experimentell zu überprüfen, da dies ein Ändern der Uhr erfordern würde.

Debian verwendet die Vixie Cron- Implementierung, auf die im Wikipedia-Artikel verwiesen wird. Das Format für Crontab-Ausdrücke wird in erklärt man 5 crontab, was etwas schwierig ist, da man crontabes nicht dasselbe ist (Standardabschnitt 1 ist der Befehl crontab, Abschnitt 5 ist für das Format von "Crontab" -Dateien).

Es wird nicht 'L' erwähnt.

WRT die Alternativen von SO, die überprüfte Antwort ist am einfachsten zu folgen und erfordert kein externes Skript usw. OTOH, es gibt ein Schaltjahrproblem ...

Goldlöckchen
quelle
Ja, Sie könnten eine Liste am 28,29 verwenden, aber dann würden Sie 2 Läufe in einem Schaltjahr bekommen :(
Drav Sloan
0

Mein Skript hat diese Funktion, es ist kein natives Cron, aber es wird den Trick machen.

http://xr09.github.io/cron-last-sunday/

Beispiele:

# every last sunday
30 6 * * 7 root run-if-today L && /root/myscript.sh

# every third tuesday
30 6 * * 2 root run-if-today 3 && /root/myscript.sh
MGP
quelle