Крон: Получать только ошибки в электронных письмах?

39

Наконец-то я установил реалистичное расписание резервного копирования своих данных с помощью сценария оболочки, который обрабатывается cron через короткие промежутки времени. К сожалению, я продолжаю получать пустые электронные письма каждый раз, когда выполняется CRON, а не только когда что-то идет не так.

Можно ли заставить CRON отправлять электронные письма только тогда, когда что-то идет не так, т.е. мой TARне выполняется как задумано?

Вот как мой crontab настроен на данный момент;

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

Большое спасибо!

промышленные
источник

Ответы:

54

В идеале вы бы хотели, чтобы ваш скрипт резервного копирования не выводил ничего, если все идет как положено, и выводит только тогда, когда что-то идет не так. Затем используйте переменную среды MAILTO, чтобы отправить любой вывод, сгенерированный вашим скриптом, на ваш адрес электронной почты.

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

Если ваш скрипт обычно выдает результат, но вы не заботитесь об этом в cron, просто отправьте его в / dev / null, и он отправит вам электронное письмо только тогда, когда что-то будет записано в stderr.

MAILTO=email@example.com
0 */2 * * * /bin/backup.sh > /dev/null
Cakemox
источник
9
Это вряд ли идеально. Обычно вы хотите, чтобы весь вывод (stdout + stderr) отправлялся вам по электронной почте, когда команда заканчивается ненулевым кодом ошибки. В противном случае, обычно нормально сожрать хотя бы стандартный вывод. Для меня это конструктивный недостаток cron.
Witiko
3
@Witiko Я согласен; Я нашел этот вопрос, пытаясь это исправить. Я думаю, вы можете сделать свою команду cron /bin/backup.sh > log_file || (echo Backup failed with exit status $?; cat log_file)?
Даниэль Х
23

Использование скрипта- оболочки cronic выглядит хорошей идеей; чтобы использовать его, вам не нужно менять свои сценарии.

Вместо того:

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

делать:

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

Проще говоря; он будет работать беззвучно, если все идет гладко (состояние выхода 0), но если нет, он будет детально сообщать, а cron будет обрабатывать почтовые отчеты.

Больше информации на https://habilis.net/cronic/ .

Рикардо Пардини
источник
Я действительно не понимаю, как это поможет, когда проблема не что иное, как неправильная линия cron, и cron делает именно то, что ему говорят.
Джон Гарденье
3
@JohnGardeniers это помогает, потому что иногда у вас есть вывод без ошибки.
Михаил
11
Как вариант, chronicиз moreutilsпакета: joeyh.name/code/moreutils
Владимир Пантелеев
4

Вы специально указываете на то, cronчтобы всегда отправлять электронную почту, даже когда /bin/backup.sh(кстати, она должна быть /usr/local/bin) это удается. Просто пропустите | mail -s "Backup status" email@example.comчасть, и электронная почта будет отправлена ​​только тогда, когда есть выход. Вероятно, вы можете (в зависимости от вашего cron) явно указать адрес электронной почты для mail как назначение в файле crontab.

Подробнее см.

man 5 crontab
reinierpost
источник
3

Вы должны направлять stderranmd не так stdoutи stderr.

Используйте 1> /dev/nullне , 2>&1и это должно быть хорошо. Также вам может потребоваться правильно сообщить об ошибке в вашем скрипте резервного копирования.

Халед
источник
3

Вот еще один вариант, который я успешно использовал в течение многих лет - захватывать вывод и распечатывать его только при ошибке , вызывая электронную почту. Это не требует временных файлов и сохраняет весь вывод . Важной частью является то, 2>&1что перенаправляет STDERR на STDOUT.

Отправьте весь вывод через конфигурацию cron mailer по умолчанию:

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

То же самое, но с конкретным адресом и темой:

(адрес также можно изменить, установив MAILTO = xxxx для всего файла crontab)

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

Вы даже можете выполнить несколько действий в случае ошибки и добавить в электронную почту:

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

Это будет работать для простых команд. Если вы имеете дело со сложными конвейерами ( find / -type f | grep -v bla | tar something-or-other), то вам лучше переместить команду в скрипт и запустить скрипт, используя вышеупомянутый подход. Причина в том, что если какая-либо часть канала будет выводиться в STDERR, вы все равно будете получать электронные письма.

Akom
источник