ubuntuusers.de

Für diese Funktion musst du eingeloggt sein.

cronjob am Montag und 1. im Monat

Status: Gelöst | Ubuntu-Version: Server 20.04 (Focal Fossa)
Antworten |

steff123

Anmeldungsdatum:
2. April 2010

Beiträge: 90

Hey, ein cronjob soll am Montag oder am ersten Tag eines Monats ausgeführt. Jeweils 1 Uhr Nachts. Ich würde folgende Zeilen machen

1
2
3
# m h dom mon dow user  command
0  1   * * 1   root      bla.sh
0  1   1 * 2-7 root      bla.sh

Passt das soweit?

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4450

Wohnort: Göttingen

Nee, das entspricht zwar dem, wie man es intuitiv machen würde, aber so funktioniert es nicht, denn so würde es durch die zweite Zeile an jedem 1. des Monats und jeden Dienstag bis Freitag ausgeführt.

So ganz verstehe ich allerdings deine Aussage "soll am Montag oder am ersten Tag eines Monats ausgeführt" nicht. Also das oder bei der Aussage ist mir unklar. Soll das heißen, an jedem Montag und jedem ersten Tag des Monats?

So würde der Job am ersten Montag jeden Monats ausgeführt:

0 1 1-7 * * [ $(date +\%u) = 1 ] && bla.sh

ChickenLipsRfun2eat Team-Icon

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12067

Ich würde das wohl mit systemd/Timer Units machen. Einfacher und verständlicher. Der cronjob wird eh zu ner unit umgewandelt.

Am hilfreichsten wäre wohl Calendar Events, mit etwas wie
Mon *-*-1 11:12:13 (jedes Jahr, an jedem ersten, wenn dieser ein Montag ist)

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13176

steff123 schrieb:

Hey, ein cronjob soll am Montag oder am ersten Tag eines Monats ausgeführt. Jeweils 1 Uhr Nachts. Ich würde folgende Zeilen machen

Du meinst, jeden Montag und am ersten Tag des Monats, oder?

Passt das soweit?

Nein, Du nutzt keine Systemd-Timer. 😛

steff123

(Themenstarter)

Anmeldungsdatum:
2. April 2010

Beiträge: 90

Danke Euch. Das "oder" war eher mathematisch gemeint. Das Skript soll in beiden Fällen ausgeführt werden, entweder ein Montag oder der 1. im Monat. Systemd-Timer stehen noch auf meine Todo-Liste. Die crontab finde ich einfach schön übersichtlich. Ist ja nur ne private Maschine.

Ich mache jetzt daraus einen Einzeiler. Da verstehe ich am schnellsten was damit gemeint ist 😉

0 1 * * * [[ $(date +%u) -eq 1 || "$(date +%d)" == "01" ]] && bla.sh

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13176

steff123 schrieb:

Danke Euch. Das "oder" war eher mathematisch gemeint.

Dann hätte man besser gesagt, "es soll ausgeführt werden, wenn der erste oder Montag ist". So, wie Du es formuliert hast, klingt es eher nach einem Exklusiv-Oder.

Das Skript soll in beiden Fällen ausgeführt werden, entweder ein Montag oder der 1. im Monat. Systemd-Timer stehen noch auf meine Todo-Liste. Die crontab finde ich einfach schön übersichtlich. Ist ja nur ne private Maschine.

Warum sollte man da nicht auf der Höhe der Zeit sein? Systemd ist halt der Standard und steuert den ganzen Bootprozess usw.

Ich mache jetzt daraus einen Einzeiler. Da verstehe ich am schnellsten was damit gemeint ist 😉

0 1 * * * [[ $(date +%u) -eq 1 || "$(date +%d)" == "01" ]] && bla.sh

Funktioniert das? Ich finde es total umständlich und fehleranfällig, sowohl cron als auch ein Skript entscheiden zu lassen, wann was passiert. Dann würde ich die Entscheidung ins Skript verlegen. Viel besser ist aber doch

0 1 1 * 1 /pfad/zu/bla.sh

Denn, wie wir aus man -s 5 crontab wissen:

Note: The day of a command's execution can be specified by two fields — day of month, and day of week. If both fields are restricted (i.e., don't start with *), the command will be run when either field matches the current time.

Es folgt ein Beispiel, das fast genau Deinen Anwendungsfall beschreibt.

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4450

Wohnort: Göttingen

Also wenn es tatsächlich sowohl an jedem Montag als auch am ersten des Monats ausgeführt werden soll, dann geht es tatsächlich auch so:

0 1 1 * 1

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4450

Wohnort: Göttingen

ChickenLipsRfun2eat: Du sagst "Der cronjob wird eh zu ner unit umgewandelt." Wo finde ich diese Units denn? Ich hatte mal nach gesucht und finde unter /etc, /var und /run schonmal nichts.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11250

Wohnort: München

Doc_Symbiosis schrieb:

ChickenLipsRfun2eat: Du sagst "Der cronjob wird eh zu ner unit umgewandelt." Wo finde ich diese Units denn? Ich hatte mal nach gesucht und finde unter /etc, /var und /run schonmal nichts.

Dazu muss das Paket systemd-cron installiert sein (vgl. https://manpages.ubuntu.com/manpages/focal/man8/systemd-crontab-generator.8.html - das beißt sich mit dem Metapaket ubuntu-standard und ist daher OOTB nicht installiert).

Man sieht dann zusätzliche aktive Timer Units für die Ausführung der Cronjobs:

$ systemctl list-timers cron*
NEXT                        LEFT                LAST PASSED UNIT                                 ACTIVATES                             
Sun 2021-07-18 09:17:00 UTC 6min left           n/a  n/a    cron-hourly.timer                    cron-hourly.target                    
Sun 2021-07-18 17:14:00 UTC 8h left             n/a  n/a    cron-popularity-contest-root-0.timer cron-popularity-contest-root-0.service
Mon 2021-07-19 06:25:00 UTC 21h left            n/a  n/a    cron-daily.timer                     cron-daily.target                     
Mon 2021-07-19 06:47:00 UTC 21h left            n/a  n/a    cron-weekly.timer                    cron-weekly.target                    
Sun 2021-08-01 06:52:00 UTC 1 weeks 6 days left n/a  n/a    cron-monthly.timer                   cron-monthly.target 

Für diese regelmäßigen cron-Aufrufe werden keine extra Units generiert, da läuft einfach ein run-parts über das entsprechende Verzeichnis:

$ systemctl cat cron-hourly.service 
# /lib/systemd/system/cron-hourly.service
[Unit]
Description=systemd-cron hourly script service
Documentation=man:systemd.cron(7)
PartOf=cron-hourly.target
ConditionDirectoryNotEmpty=/etc/cron.hourly
OnFailure=cron-failure@%i.service

[Service]
Type=oneshot
IgnoreSIGPIPE=false
ExecStart=/bin/run-parts --report /etc/cron.hourly 

Und wenn man dann z.B. in der /etc/crontab einen Eintrag anlegt:

10  *   * * *   root    /usr/bin/logger -t test "I am a crontab entry"

Dann werden eine Timer-Unit und eine Systemd-Unit generiert und aktiviert:

$ systemctl list-timers *crontab*
NEXT                        LEFT       LAST PASSED UNIT                      ACTIVATES                  
Sun 2021-07-18 10:10:00 UTC 51min left n/a  n/a    cron-crontab-root-0.timer cron-crontab-root-0.service

1 timers listed.
Pass --all to see loaded but inactive timers, too.
$ systemctl cat cron-crontab-root-0.timer cron-crontab-root-0.service
# /run/systemd/generator/cron-crontab-root-0.timer
[Unit]
Description=[Timer] "10 * * * * root /usr/bin/logger -t test "I am a crontab entry""
Documentation=man:systemd-crontab-generator(8)
PartOf=cron.target
SourcePath=/etc/crontab

[Timer]
Unit=cron-crontab-root-0.service
OnCalendar=*-*-* *:10:00

# /run/systemd/generator/cron-crontab-root-0.service
[Unit]
Description=[Cron] "10 * * * * root /usr/bin/logger -t test "I am a crontab entry""
Documentation=man:systemd-crontab-generator(8)
SourcePath=/etc/crontab
OnFailure=cron-failure@%i.service

[Service]
Type=oneshot
IgnoreSIGPIPE=false
KillMode=process
ExecStart=/bin/sh /run/systemd/generator/cron-crontab-root-0.sh
Environment=SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 

steff123

(Themenstarter)

Anmeldungsdatum:
2. April 2010

Beiträge: 90

Doc_Symbiosis schrieb:

Also wenn es tatsächlich sowohl an jedem Montag als auch am ersten des Monats ausgeführt werden soll, dann geht es tatsächlich auch so:

0 1 1 * 1

Danke. Da war ich echt blind und hatte mich von dem Beispiel im zweiten Post irritieren lassen.

Antworten |