Ausführen eines Scripts per Cron-Job

Chris81T

Member
Hi zusammen,

mir gehen aktuell bei einer Flanke die Ideen was aus und hoffe dass eventuell von euch jemand Erfahrungen dazu hat.

Worum geht es?

Ich habe ein Script, welches täglich abends um 21 Uhr ausgeführt werden soll. Daher war mein erster Gedanke, dass ich auf meiner QNap einen Eintrag in der Crontab hinterlege. Bei der QNap sollte man nicht auf herkömmlichen Wege die Einträge pflegen - so besagt es die Dokumentation. Daher habe ich mich an diese hier gehalten.

Die Aufgabe des Scripts ist es, per Docker einen Container zu starten:

Code:
#!/bin/bash
docker start certbotgodaddy

Die Routine innerhalb de Containers beendet sich nach einem Moment selbstständig. Hintergrund: Dort wird die Gültigkeit eines Zertifikats geprüft.

Das Script liegt ausführbar unter dem /share/ Bereich (Über die QNap WebApp habe ich mir dort einen Ordner für Scripte angelegt).

Zum Test habe ich dann manuell das Script angestoßen und konnte über die Docker Logs erkennen, dass die Prüfung anhand eines Timestamps erfolgreich durchgeführt wurde. Wenn ich nun den Job nach der Doku von QNap hinterlegt habe und den Dienst per Terminal einmal softwareseitig neugestartet habe - was am gleichen Tag vor 21 Uhr gemacht wurde, wird ebenfalls das Script durchgeführt.

Soweit so gut. Nun ist es so, dass die QNap bei mir gegen Mitternacht heruntergefahren wird und morgens wieder gestartet wird. Bedeutet, wenn ich nach einem Tag die Logs prüfe, kann ich keinen Eintrag bzgl. Durchführung feststellen!

Nach vielen hin und her - und weil ich die Problemquelle noch nicht richtig identifizieren kann (eher was auf der Docker Flanke, oder doch eher was in Richtung Cron Job), habe ich mein Script etwas erweitert:

Code:
#!/bin/bash
docker start certbotgodaddy >> /share/jarvis/scripts/logs/resultCode.txt
touch "/share/jarvis/scripts/logs/cron-exec-log_$(date +'%Y%m%d%H%M.%S')"

Einmal möchte ich, dass das Script einfach eine leere Datei mit nem Zeitstempel anlegt (Zeile2), um damit festzustellen, ob das Script ausgeführt wurde. Dann ist es so, wenn man händisch den "docker start..." Befehl ausführt, dass man einen kleinen Result-Code zurückbekommt. Diesen lass ich mir einfach per Pipe in eine Datei schreiben.

Auch hier, wenn ich manuell das Script aufrufe, wird die timestamp Datei anglegt und auch was in die txt Datei geschrieben. Schaue ich einen Tag später nach, stelle ich fest, dass die timestamp Datei angelegt wurde, aber nichts in die txt Datei eingegangen ist. Genausowenig findet man was in den Docker Logs des Containers.

Ein zeitliches Problem kann es auch nicht sein. Würde das Script direkt zum Neustart ausgeführt, wäre potentiell Docker noch nicht final hochgefahren, aber um 21 Uhr ist alles aktiv.

Ich habe keine Idee mehr. Hat von euch jemand noch eine Idee hierzu? Ich bin gespannt :)

Die letzte Flanke wäre ggf. der User, welcher von der Crontab genutzt wird, dass hier in Richtung Docker ne Restriktion ist. Aber habe ich den Cron Service vor 21 neugestartet, klappt es ja...



Viele Grüße!
 
Vielleicht noch als kurze Erklärung zu @FSC830 guter Anmerkung.

Dein Befehl leitet zur Zeit den Standard-Output an die Datei um, dabei wird (>>) eine Datei im anhängenden Modus verwendet. Wenn Du nur einen ">" nimmst, dann wird die Datei vorher geleert.

Darüber hinaus kennen unixoide Systeme zwei weitere, sogenannte, "file descriptor" (file wegen der "Unix-Philosophie "everything is a file") nämlich 2 := Standard-Error und 0 := Standard-Input. Der Standard-Output ist der Vollstänigkeit halber übrigens 1.

Durch das Befehlsadditiv "2>&1" sagst Du nun dem System, dass das alles was er in Standard-Error (2) schreiben würde, stattdessen an Standard-Output (1) geschrieben werden soll. Das "&" ist hierbei der Operator, der die "1" als einen "file descriptor" kennzeichnet. Ohne würde nämlich eine Datei mit Namen "1" im Verzeichnis angelegt werden.

Das Ganze fällt Dir im "manuellen Betrieb" meist nicht auf, weil auf der Shell 1 und 2 stets auf die Shell-Console zeigen. ;) Dein Befehl leitet dann aber nur den Standard-Ouput von der Shell-Console in die Datei um.

Versuch also mal:
Code:
docker start certbotgodaddy 2>&1 >>/share/jarvis/scripts/logs/resultCode.txt
 
Zuletzt bearbeitet:
Besten Dank euch für die Hinweise und Erklärungen. (y)

Ich hab dies nun hinterlegt und schaue heute Abend dann einmal, was bei rum kommt. Werde berichten..
 
So ich habe soeben einmal nachgeschaut:

[/share/jarvis/scripts/logs] # ls -l
total 0
-rw-r--r-- 1 admin administrators 0 2023-04-18 21:00 cron-exec-log_202304182100.00
-rw-r--r-- 1 admin administrators 0 2023-04-19 21:00 cron-exec-log_202304192100.01
-rw-r--r-- 1 admin administrators 0 2023-04-20 21:00 cron-exec-log_202304202100.00
-rw-r--r-- 1 admin administrators 0 2023-04-18 21:00 resultCode.txt

Laut dem Datum wurde die resultCode.txt nicht angepackt (Heute der 20.4.). Ich habe nun das Script nochmals händisch aufgerufen:

[/share/jarvis/scripts/logs] # ls -l
total 4
-rw-r--r-- 1 admin administrators 0 2023-04-18 21:00 cron-exec-log_202304182100.00
-rw-r--r-- 1 admin administrators 0 2023-04-19 21:00 cron-exec-log_202304192100.01
-rw-r--r-- 1 admin administrators 0 2023-04-20 21:00 cron-exec-log_202304202100.00
-rw-r--r-- 1 admin administrators 0 2023-04-20 22:06 cron-exec-log_202304202206.01
-rw-r--r-- 1 admin administrators 15 2023-04-20 22:06 resultCode.txt
Inhalt:

So sieht das Script aktuell aus:

Code:
#!/bin/bash
docker start certbotgodaddy 2>&1 >> /share/jarvis/scripts/logs/resultCode.txt
touch "/share/jarvis/scripts/logs/cron-exec-log_$(date +'%Y%m%d%H%M.%S')"

Mir geht es ja nun nicht darum, dass hier das in die txt-Datei geschrieben wird, sondern ich möchte feststellen, dass der Container ausgeführt wird. Wenn ich über Portainer in die Logs schaue:

2023-04-20T20:06:05.182636589Z Certificate not yet due for renewal
2023-04-20T20:06:05.183336145Z
2023-04-20T20:06:05.183359306Z - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2023-04-20T20:06:05.183369913Z Certificate not yet due for renewal; no action taken.
2023-04-20T20:06:05.183378652Z - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2023-04-20T20:06:05.185645729Z Saving debug log to /var/log/letsencrypt/letsencrypt.log

Dann finde ich für heute die Einträge von dem manuell ausgeführtem Aufruf von eben, aber nicht mehr.

Wenn ihr sagt, dass das Script bzgl. Wegschreiben passen sollte, dann wird der Container einfach nicht gestartet. Aber was ist das Problem?
 
Ich arbeite nicht so viel mit Docker; aber sollte er, nicht wenn er den Container nicht ausführen kann, trotzdem was ins Log schreiben?
Sowas wie "Startfehler" oder so?
 
Das würde ich auch erwarten. In der Dokumentation zu "docker start" steht leider nicht viel drin. Es gibt lediglich die Option:

Name, shorthandDefaultDescription
--attach , -aAttach STDOUT/STDERR and forward signals

die mir so noch nicht bekannt war. Aber hier wird das, was ins Docker Log geschrieben werden soll, dann hier über stdout mit ausgegeben:

certbotgodaddy
Certificate not yet due for renewal

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Certificate not yet due for renewal; no action taken.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Testweise hab ich Portainer Stack (compose) eine URL invalid gemacht, die txt Datei gelöscht und dann das Script ausgeführt:
[/share/jarvis/scripts/logs] # ../certbotcheck.sh
Saving debug log to /var/log/letsencrypt/letsencrypt.log
An unexpected error occurred:
requests.exceptions.InvalidSchema: No connection adapters were found for 'Xhttps://acme-v02.api.letsencrypt.org/directory'
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.
[/share/jarvis/scripts/logs] # ls -l
total 0
-rw-r--r-- 1 admin administrators 0 2023-04-18 21:00 cron-exec-log_202304182100.00
-rw-r--r-- 1 admin administrators 0 2023-04-19 21:00 cron-exec-log_202304192100.01
-rw-r--r-- 1 admin administrators 0 2023-04-20 21:00 cron-exec-log_202304202100.00
-rw-r--r-- 1 admin administrators 0 2023-04-20 22:06 cron-exec-log_202304202206.01
-rw-r--r-- 1 admin administrators 0 2023-04-20 22:29 cron-exec-log_202304202229.53
-rw-r--r-- 1 admin administrators 0 2023-04-20 22:34 cron-exec-log_202304202234.11
-rw-r--r-- 1 admin administrators 0 2023-04-20 22:34 cron-exec-log_202304202234.45
-rw-r--r-- 1 admin administrators 0 2023-04-20 22:34 resultCode.txt
[/share/jarvis/scripts/logs] #

Der Error wird hier ausgeplottet, aber nicht in die Datei überführt (0 Bytes). Beim Erfolgsfall landet es auch in der Datei. Also kann es gut sein, dass nach dem Neustart der QNap, wenn dann abends das Script ausgeführt wird, dass der Fehler nicht getrackt wird.
 
Der Error wird hier ausgeplottet, aber nicht in die Datei überführt (0 Bytes). Beim Erfolgsfall landet es auch in der Datei.
??? Also im Fehlerfall Meldung auf der Console, aber nicht im Log und bei Erfolg Ausgabe auf Konsole und im Log?
Habe ich das richtig verstanden?

Mit Docker habe ich auch nichts am Hut, aber mein Scripte protokollieren alles, was ich will.

Gruss
 
Generell würde es vermutlich helfen, wenn man mal einen Blick in die entsprechenden (System-)Logs zu werfen, irgendwo muss ja etwas stehen...
 
Ich hatte mich nach einer kleinen Pause hieran nochmal versucht. Leider habe ich in den /var/log's nichts passendes gefunden. Muss dazu aber auch sagen, dass ich nicht sicher bin, wo genau Cron bei QNap loggt. Das kann ja von Distribution zu Distribution unterschiedlich sein.

Testweise hatte ich nun versucht, einen anderen Docker Befehl ausführen zu lassen. Konkret die Logs von einem Container ausgeben zu lassen. Auch hier kann ich keine Aktivität erkennen.

Meines Wissens muss der User, welcher Docker Commands ausführen möchte, Teil der Docker Gruppe sein. Welcher User wird im Kontext von Cron genutzt? Bzw. kann man Cron mitteilen, mit welchem User ein Befehl / Script ausgeführt werden soll?
 
Meinst Du so etwas hier:

1 1 * * * username /path/to/your/script.sh

Das geht in crontab und in cron.d
 
Zuletzt bearbeitet:
Also,

die dedizierte Angabe eines Users hatte mir nicht weitergeholfen. Aber hatte noch eine Idee dazu bekommen. In meinem Script habe ich direkt "docker" aufgerufen. Das fordert aber auch ein, dass der PATH auch gesetzt ist. Daher habe ich einmal identifiziert, wo genau bei der QNap -> Container Station die Binaries abgelegt werden und das Script so angepasst, dass nun der absolute Pfad zum Docker Command hinterlegt ist:

Code:
/share/CACHEDEV1_DATA/.qpkg/container-station/bin/docker start certbotgodaddy ...

Falls jmd. ähnliche Probleme hat, kann es u.U. sein, dass der Pfad variiert. Zu guter Letzt konnte ich eben in den Logs zur hinterlegten Zeit zum Cronjob entsprechende Logs entnehmen.

Daher sieht's nun nach gelöst aus.

Auf jeden Fall vielen Dank an alle für den guten Input!
 

Zurzeit aktive Besucher

Keine Mitglieder online.

Letzte Anleitungen

Statistik des Forums

Themen
4.492
Beiträge
46.162
Mitglieder
4.121
Neuestes Mitglied
Dieter 55
Zurück
Oben