Cron: Nur Fehler in E-Mails bekommen?

38

Ich habe endlich einen realistischen Backup-Zeitplan für meine Daten durch ein Shell-Skript erstellt, das von cron in engen Intervallen verarbeitet wird. Leider bekomme ich jedes Mal leere E-Mails, wenn der CRON ausgeführt wurde und nicht nur, wenn etwas schief geht.

Ist es möglich, CRON nur dann zum Senden von E-Mails zu veranlassen, wenn etwas schief geht, z. mein TARnicht wie vorgesehen ausführen?

Hier ist, wie meine Crontab für den Moment eingerichtet ist;

0 */2 * * * /bin/backup.sh 2>&1 | mail -s "Backup status" email@example.com

Vielen Dank!

Industrie
quelle

Antworten:

53

Im Idealfall sollte Ihr Backup-Skript nichts ausgeben, wenn alles wie erwartet verläuft, und nur dann eine Ausgabe erzeugen, wenn etwas schief geht. Verwenden Sie dann die Umgebungsvariable MAILTO, um alle von Ihrem Skript generierten Ausgaben an Ihre E-Mail-Adresse zu senden.

MAILTO=email@example.com
0 */2 * * * /bin/backup.sh

Wenn Ihr Skript normalerweise eine Ausgabe erzeugt, es Ihnen in cron aber egal ist, senden Sie es einfach an / dev / null und Sie erhalten eine E-Mail, wenn etwas an stderr geschrieben wurde.

MAILTO=email@example.com
0 */2 * * * /bin/backup.sh > /dev/null
Cakemox
quelle
9
Das ist kaum ideal. Sie möchten im Allgemeinen die gesamte Ausgabe (stdout + stderr) per E-Mail erhalten, wenn der Befehl mit einem Fehlercode ungleich Null endet. Ansonsten ist es in der Regel in Ordnung, zumindest etwas zu verschlingen. Für mich ist dies ein Designfehler von Cron.
Witiko
3
@Witiko Ich stimme zu; Ich habe diese Frage gefunden, um das zu beheben. Ich vermute, Sie können Ihren Cron-Befehl machen /bin/backup.sh > log_file || (echo Backup failed with exit status $?; cat log_file)?
Daniel H
22

Die Verwendung von cronic- Wrapper-Skripten scheint eine gute Idee zu sein. Um es zu benutzen, müssen Sie Ihre Skripte nicht ändern.

Anstatt:

 0 1 * * * /bin/backup.sh 2>&1 | mail -s "Backup status" email@example.com

machen:

 MAILTO=email@example.com
 0 1 * * * cronic /bin/backup.sh

Einfach gesagt; es wird still laufen, wenn alles glatt läuft (Exit-Status 0), aber es wird ausführlich berichtet, wenn nicht, und cron wird die Mail-Berichterstellung behandeln.

Weitere Informationen unter https://habilis.net/cronic/ .

Ricardo Pardini
quelle
Ich verstehe wirklich nicht, wie das helfen wird, wenn das Problem nur eine falsche Cron-Zeile ist und Cron genau das tut, was ihm gesagt wurde.
John Gardeniers
3
@JohnGardeniers es hilft, weil man manchmal fehlerfrei ausgegeben hat.
Mikhail
11
Alternativ chronicaus dem moreutilsPaket: joeyh.name/code/moreutils
Vladimir Panteleev
4

Sie weisen ausdrücklich cronan, immer E-Mails zu senden, auch wenn dies /bin/backup.sh(im /usr/local/binÜbrigen) erfolgreich sein sollte. Lassen Sie einfach den | mail -s "Backup status" [email protected]Teil weg und die E-Mail wird nur gesendet, wenn eine Ausgabe erfolgt. Sie können wahrscheinlich (abhängig von Ihrer cron) die E-Mail-Adresse, an die gesendet werden soll, explizit als Zuweisung in der crontab-Datei festlegen.

Einzelheiten finden Sie unter

man 5 crontab
reinierpost
quelle
3

Du solltest die stderranmd nicht beides stdoutund leiten stderr.

Verwenden Sie 1> /dev/nullnicht 2>&1und es sollte in Ordnung sein. Möglicherweise müssen Sie den Fehler auch in Ihrem Sicherungsskript korrekt melden.

Khaled
quelle
3

Hier ist eine weitere Variante, die ich seit vielen Jahren erfolgreich verwende: Erfassen Sie die Ausgabe und drucken Sie sie nur bei Fehlern aus , um eine E-Mail auszulösen. Dies erfordert keine temporären Dateien und behält die gesamte Ausgabe bei . Der wichtige Teil ist der 2>&1, der STDERR zu STDOUT umleitet.

Senden Sie die gesamte Ausgabe über die Standard-Cron-Mailer-Konfiguration:

1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || echo "$OUTPUT"

Gleich, aber mit einer bestimmten Adresse und Betreff:

(Die Adresse kann auch geändert werden, indem MAILTO = xxxx für die gesamte crontab-Datei festgelegt wird.)

1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || echo "$OUTPUT" | mail -s "Failed to backup" an@email.address

Sie können sogar mehrere Aktionen bei Fehlern ausführen und der E-Mail hinzufügen:

1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || {echo "$OUTPUT" ; ls -ltr /backup/dir ; }

Dies funktioniert für einfache Befehle. Wenn Sie es mit komplexen Pipes ( find / -type f | grep -v bla | tar something-or-other) zu tun haben, sollten Sie den Befehl in ein Skript verschieben und das Skript mit dem oben beschriebenen Ansatz ausführen. Der Grund ist, dass Sie immer noch E-Mails erhalten, wenn ein Teil der Pipe an STDERR ausgegeben wird.

Akom
quelle