mikrocontroller.net

Forum: PC-Programmierung [cronjob, crontab]:Wo gehen die Ausgaben hin?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Osmund (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Crontab:
@reboot /home/pi/sdt.py &
*/5 * * * * /home/pi/sensor.py &

Das Script 'sensor.py' schreibt alle 5 Minuten Werte in eine Datei und 
gibt gleichzeitig die Werte auf der Konsole aus. Wird das Script per 
Hand gestartet funktioniert dies auch. Per 'cronjob' wird die Datei 
korrekt beschrieben, nur auf der Konsole erscheint nichts.

Wo landet die Ausgabe des Scripts?

von H2O (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Meist geht STDOUT per Mail an den User, unter dem der Job läuft.
Musst halt schauen, wie cron bei dir konfiguriert ist.

von Rolf M. (rmagnus)


Bewertung
1 lesenswert
nicht lesenswert
Auf welcher Konsole soll das denn erscheinen? cron-Jobs werden vom 
cron-Daemon gestartet und nicht von irgendeiner Konsole aus.

Aus der manpage von cron:
"When executing commands, any output is mailed to the owner of the 
crontab (or to the user named in the  MAILTO  environment  variable  in 
the crontab, if such exists).  The children copies of cron running these 
processes have their name coerced to uppercase, as will be seen in the 
syslog and ps output."

von Osmund (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für eure Antworten.

Die 'crontab' wurde um den Mail-Eintrag erweitert:
...
MAILTO=pi
...

Die Variable MAIL enthält jetzt das Ziel:
echo $MAIL
/var/mail/pi

Nur - es kommt keine Mail an. Das Verzeichnis '/var/mail' ist leer.

Woran kann das liegen?

von woas i nit (Gast)


Bewertung
0 lesenswert
nicht lesenswert
ich würde die ausgaben nach stdout und stderr getrennt in logfiles 
umleiten und diese dann auch gleich mit logrotate rotieren lassen.

damit habe ich dann (passende programmierung vorausgesetzt):
* die werte in einer datei, die auch weiter verarbeitet werden kann 
(z.b. csv)
* debug/protokoll ausgaben in einer rotierten datei
* fehler in einer eigenen log-datei

so in der art
*/5 * * * * /foo/bar > /foo/out.log 2> /foo/err.log

von Osmund (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Zwischenstand:

Nach der händischen Einrichtung von '/var/mail/pi' kam die Nachricht:
 You have mail in /var/mail/pi
 ls -l /var/mail/pi
total 0

Bloß da war nichts!

@ woas i nit

Werde ich ausprobieren.

von Rolf M. (rmagnus)


Bewertung
1 lesenswert
nicht lesenswert
Osmund schrieb:

> Die Variable MAIL enthält jetzt das Ziel:
> echo $MAIL
> /var/mail/pi
>
> Nur - es kommt keine Mail an. Das Verzeichnis '/var/mail' ist leer.

Was passiert denn, wenn du "mail" aufrufst?
Aber wie "woas i nit" schon schrieb: Am besten leitest du die Ausgabe 
selber in ein File um.

Osmund schrieb:
> Nach der händischen Einrichtung von '/var/mail/pi' kam die Nachricht:

Hat der MTA denn auch Schreibzugriff auf dieses Verzeichnis?

: Bearbeitet durch User
von Osmund (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Rolf M. schrieb:

> Was passiert denn, wenn du "mail" aufrufst?

-bash: mail: command not found

> Hat der MTA denn auch Schreibzugriff auf dieses Verzeichnis?

Ja.

von Sheeva P. (sheevaplug)


Bewertung
-1 lesenswert
nicht lesenswert
Osmund schrieb:
>
> @reboot /home/pi/sdt.py &
> */5 * * * * /home/pi/sensor.py &
> 

Warum versetzt Du die Skripte mit '&' in den Hintergrund? Und was macht 
der @reboot-Eintrag -- startet der etwa eine Art Server? Da wäre es 
vermutlich sinnvoller, ein SysV-Initskript oder heutzutage besser ein 
systemd Unitfile zu verwenden... oder, wenn man ein bisschen lustig 
'drauf ist, so etwas wie supervisord, monit oder runit.

Was die Ausgabe der Skripte angeht... IMHO sollten Cron-Skripte nur dann 
eine Ausgabe erzeugen, wenn etwas schiefgelaufen ist. Wenn erzeugte 
Daten weitergegeben werden müssen, so ist es üblicherweise sinnvoller, 
diese in einer Datei oder einer Datenbank (das muß natürlich keine 
SQL-Datenbank, sondern kann auch etwas leichtgewichtiges wie Redis oder 
etwas Fettes wie Elasticsearch sein) zu sichern -- oder die Mail direkt 
aus dem Cron-Skript zu generieren und zu versenden. Letzteres bietet 
dann auch den Vorteil, daß auch MIME-Mails mit Anhängen erzeugt werden 
können.

So können auch mehrere Dateien zum Beispiel mit Binärdaten, 
strukturierten Daten im JSON, YAML- oder CSV-Format, generierten 
Grafiken und Ähnliches angehängt und auf einem passenden Mail User Agent 
direkt dargestellt bzw. mit der richtigen Anwendung geöffnet werden. Für 
bestimmte Zielgruppen können damit auch gleich reine HTML-E-Mails 
(igitt) oder eine Kombination aus PlainText- und HTML-Mails erzeugt 
werden, die dann (je nach MUA) gleich korrekt dargestellt werden. Für 
Python gibt es für diese Aufgabe die Pakete email zum Erzeugen von 
E-Mails, sowie smtplib für deren Versand.

Außerdem, wenn man schon mit einer Ausgabeumleitung arbeiten will: warum 
dann nicht auf das eigens für solche Zwecke vorgesehene Programm 
logger(1)? Das erzeugt dann auch gleich korrekte Zeitstempel im Log, und 
es können Metainformationen wie Loglevel, -Facility und Tags und weitere
strukturierte Felder etwa für systemds journald mitgegeben werden. Und 
da die Nachrichten im Syslog oder -Journal landen, wird auch ohne 
weitere Konfiguration direkt korrekt rotiert...

Darüber hinaus besitzt Python zum Logging über ein sehr leistungsfähiges 
Modul, das überraschenderweise auf den Namen "logging" hört. Und das 
kann wirklich so ziemlich alles, was das Herz begehrt, natürlich auch 
auf die standardmäßigen Logging-Mechanismen des zugrundeliegenden 
Systems, also beispielsweise (r)syslog oder systemd loggen, aber auch 
Lognachrichten via SMTP, HTTP(S) GET/POST, Sockets oder eine Message 
Queue schreiben.

Ganz grundsätzlich ist ein Logging aber nicht für den Transport oder die 
Speicherung von Daten gedacht, sondern für Lognachrichten, die die 
Aufrufe, Zustände, Fehler und ggf. Performancedaten eines Systems und 
der Prozesse dokumentieren. In Lognachrichten können zwar Daten 
enthalten sein, sollten es aber nur dann, wenn sie zum Verständnis der 
Lognachricht nötig sind. In allen anderen Fällen ist es keine gute Idee, 
Daten über Loggingmechanismen zu transportieren und / oder zu speichern. 
Schon alleine die Daten am Ende aus den Logdateien zu extrahieren, ... 
wärgs! Viele Loggingsysteme sind auch ausgesprochen schlecht, wenn es um 
mehrzeilige Nachrichten, binäre Daten und Ähnliches geht, und so 
aufgeblasene Logdateien werden spätestens dann zum Problem, wenn ein 
Monitoring genutzt werden soll.

Auch vor dem Hintergrund, daß Logdateien üblicherweise rotiert werden, 
ist es keine gute Idee, Applikationsdaten darin zu speichern, denn die 
werden natürlich am Ende der Rotation einfach verworfen. Wenn sie bis 
dahin nicht aus den Lognachrichten extrahiert und anderweitig 
gespeichert worden sind, dann sind die Daten... genau, hinfort! Das kann 
zwar die Idee sein, muß es aber nicht... ;-)

Zuletzt, nur so als Hinweis: Python selbst bietet einen Scheduler in dem 
Builtin-Modul "sched", und es gibt eine externe Bibliothek namens 
schedule [1]. Wenn also eh ein langlaufender Serverprozeß gestartet 
wird, benötigt man keinen Cron-Daemon, sondern kann eines dieser Module 
verwenden und die notwendigen Arbeiten von dem langlaufenden Prozeß 
ausführen lassen; das hat den Vorteil, daß man alles an einem Ort hat 
und somit keine Abhängigkeiten, Synchronisierungen etc. unter seinen 
Cron-Skripten beachten muß...

[1] https://github.com/dbader/schedule

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
woas i nit schrieb:
> ich würde die ausgaben nach stdout und stderr getrennt in logfiles
> umleiten und diese dann auch gleich mit logrotate rotieren lassen.
>
> so in der art
>
*/5 * * * * /foo/bar > /foo/out.log 2> /foo/err.log

Prinzipiell halte ich das auch für ein vernünftiges Vorgehen, mache ich 
auch immer so.

Aber da oben ist ein kleiner Fehler. Es macht überhaupt keinen Sinn, den 
Output mit logrotate rotieren zu lassen, wenn Du ihn sowieso alle 5 
Minuten wieder überschreibst.

Du wolltest den Output wohl eher anhängen:
*/5 * * * * /foo/bar >>/foo/out.log 2>>/foo/err.log

von woas i nit (Gast)


Bewertung
0 lesenswert
nicht lesenswert
ja eh, mea maxima culpa

handy ist schaß zum tippen, außerdem bin ich ca 500 km von meinen 
rechnern entfernt... ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.