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

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

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

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

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

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

6 ответов

Решение

В идеале вы бы хотели, чтобы ваш скрипт резервного копирования не выводил ничего, если все идет как положено, и выводит только тогда, когда что-то идет не так. Затем используйте переменную среды 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

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

Вместо:

 0 1 * * * backup >/dev/null 2>&1

делать:

 0 1 * * * cronic backup


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

Вот еще один вариант, который я успешно использовал в течение многих лет - захватывать вывод и распечатывать его только при ошибке, вызывая электронную почту. Это не требует временных файлов и сохраняет весь вывод. Важной частью является 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, вы все равно будете получать электронные письма.

Это очень распространенная проблема, и в настоящее время (2021 год) ее лучше всего решить с помощью «хронической» из пакета moreutils , которая сделана именно для этой цели. Этот пакет доступен в большинстве дистрибутивов Linux/BSD.

      chronic runs a command, and arranges for its standard out and standard error to only be displayed if the command fails (exits nonzero or crashes). If the command succeeds, any extraneous output will be hidden.

A common use for chronic is for running a cron job. Rather than trying to keep the command quiet, and having to deal with mails containing accidental output when it succeeds, and not verbose enough output when it fails, you can just run it verbosely always, and use chronic to hide the successful output.

        0 1 * * * chronic backup # instead of backup >/dev/null 2>&1

Вы должны направлять stderr не оба stdout а также stderr,

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

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

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

man 5 crontab
Другие вопросы по тегам