Cron: Otrzymujesz tylko błędy w e-mailach?

38

W końcu utworzyłem realistyczny harmonogram tworzenia kopii zapasowych moich danych za pomocą skryptu powłoki, który jest obsługiwany przez crona w ciasnych odstępach czasu. Niestety ciągle otrzymuję puste e-maile za każdym razem, gdy CRON zostanie wykonany, i nie tylko wtedy, gdy coś pójdzie nie tak.

Czy CRON może wysyłać wiadomości e-mail tylko wtedy, gdy coś pójdzie nie tak, np. mój TARnie działa zgodnie z przeznaczeniem?

Oto, jak na razie skonfigurowano mój crontab;

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

Wielkie dzięki!

Przemysłowy
źródło

Odpowiedzi:

53

Idealnie byłoby, gdyby skrypt zapasowy nie wyświetlał nic, jeśli wszystko pójdzie zgodnie z oczekiwaniami, i produkuje dane tylko, gdy coś pójdzie nie tak. Następnie użyj zmiennej środowiskowej MAILTO, aby wysłać dane wyjściowe wygenerowane przez skrypt na Twój adres e-mail.

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

Jeśli twój skrypt normalnie generuje dane wyjściowe, ale nie przejmujesz się tym w cronie, po prostu wyślij je do / dev / null, a wyśle ​​ci e-mail tylko wtedy, gdy coś zostanie zapisane w stderr.

MAILTO=email@example.com
0 */2 * * * /bin/backup.sh > /dev/null
Cakemox
źródło
9
To nie jest idealne. Zasadniczo chcesz, aby całe wyjście (stdout + stderr) zostało wysłane e-mailem, gdy polecenie zakończy się niezerowym kodem błędu. W przeciwnym razie na ogół dobrze jest pożreć przynajmniej stdout. Dla mnie jest to wada projektowa crona.
Witiko
3
@Witiko Zgadzam się; Znalazłem to pytanie, próbując to naprawić. Myślę, że możesz wykonać polecenie crona /bin/backup.sh > log_file || (echo Backup failed with exit status $?; cat log_file)?
Daniel H
22

Korzystanie z chronicznego skryptu opakowującego wygląda na dobry pomysł; aby z niego skorzystać, nie musisz zmieniać swoich skryptów.

Zamiast:

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

robić:

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

Po prostu; będzie działał cicho, jeśli wszystko pójdzie gładko (kod wyjścia 0), ale będzie raportował w pełnym zakresie, jeśli nie, i pozwoli cronowi obsłużyć raportowanie poczty.

Więcej informacji na https://habilis.net/cronic/ .

Ricardo Pardini
źródło
Naprawdę nie rozumiem, jak to pomoże, gdy problemem jest tylko niepoprawna linia cron, a cron robi dokładnie to, co mu polecono.
John Gardeniers
3
@JohnGardeniers to pomaga, ponieważ czasami masz wyjście bez błędu.
Michaił
11
Alternatywnie, chronicz moreutilspaczki: joeyh.name/code/moreutils
Vladimir Panteleev
4

W szczególności instruujesz, cronaby zawsze wysyłać wiadomości e-mail, nawet jeśli /bin/backup.sh(tak przy okazji, powinno być /usr/local/bin). Wystarczy pominąć | mail -s "Backup status" [email protected]część, a wiadomość e-mail zostanie wysłana tylko wtedy, gdy zostanie wydrukowana. Prawdopodobnie możesz (w zależności od twojego cron) jawnie ustawić adres e-mail na mail jako zadanie w pliku crontab.

Aby uzyskać szczegółowe informacje, patrz

man 5 crontab
reinierpost
źródło
3

Powinieneś kierować i stderrnie zarówno stdouti stderr.

1> /dev/nullNie używaj 2>&1i powinno być dobrze. Ponadto może być konieczne prawidłowe zgłoszenie błędu w skrypcie kopii zapasowej.

Khaled
źródło
3

Oto kolejna odmiana, którą z powodzeniem stosuję od wielu lat - przechwytuj dane wyjściowe i drukuj je tylko w przypadku błędu , uruchamiając wiadomość e-mail. Nie wymaga to plików tymczasowych i zachowuje wszystkie dane wyjściowe . Ważną częścią jest to, 2>&1że przekierowuje STDERR do STDOUT.

Wyślij całe dane wyjściowe za pomocą domyślnej konfiguracji cron mailera:

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

To samo, ale z określonym adresem i tematem:

(adres można również zmienić, ustawiając MAILTO = xxxx dla całego pliku crontab)

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

Możesz nawet wykonać wiele działań w przypadku błędu i dodać do wiadomości e-mail:

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

Będzie to działać w przypadku prostych poleceń. Jeśli masz do czynienia ze złożonymi potokami ( find / -type f | grep -v bla | tar something-or-other), lepiej jest przenieść komendę do skryptu i uruchomić skrypt przy użyciu powyższego podejścia. Powodem jest to, że jeśli jakakolwiek część potoku wysyła do STDERR, nadal będziesz otrzymywać e-maile.

Akom
źródło