Crontab и отправка почты
На днях столкнулся с проблемой. На моем ноуте крутится несколько crontab-задач. Хотелось бы видеть, когда сработала каждая из них и если нет, то почему. Какое-то время я выкручивался с помощью логов. Оба канала (stdout и stderr) перехватываются в общий пайп, где каждая строка предваряется текущий датой и записывается в файл. Например:
SHELL=/bin/bash
0 */3 * * * /path/to/command &> >( while read line; do echo "$(date): ${line}"; done >> /Users/ivan/logs/command.log)
В результате и обычный, и ошибочный выхлоп оседают в файле. Выглядит это так:
Tue Jun 22 15:58:02 MSK 2021: warning: Skipping file ...
Tue Jun 22 15:58:19 MSK 2021: Completed 0 file(s) with ...
Tue Jun 22 15:59:02 MSK 2021: warning: Skipping file /Users/ivan/...
Tue Jun 22 15:59:19 MSK 2021: Completed 0 file(s) with ...
Недостаток в том, что логи нужно регулярно проверять. Об этом легко забыть на месяц, а потом выяснится, что задача не работала из-за глупой ошибки.
Тут я вспомнил, что крон умеет отправлять выхлоп задачи на почту. Если задана
переменная MAILTO=<email>
, то на эту почту свалится выхлоп. Это значит,
отпадают логи, ведь теперь достаточно проверить почту. Проверять ее можно и с
телефона, что в разы удобней.
Отправка письма работает за счет утилиты mail
. В общем виде ей пользуются так:
cat something | mail -s 'subject' friend@domain.com
Эта команда отправит письмо на сервер domain.com
, при этом отправитель будет
выглядеть как ivan@ivan.local
, то есть имя пользователя и текущего хоста. То
же самое можно получить командой:
echo `whoami`@`hostname`
Обратите внимание на кавычки – они означают выполнить выражение в новом шелле и подставить результат.
Отправленное письмо никто не получит, что потому что современные сервера
отметают письма, где айпи отправителя не совпадает с айпи его домена. Это
хорошо, иначе бы мы утонули в спаме. Будем отправлять письма с серверов Гугла. А
чтобы mail
мог подключиться к Гуглу, сделаем три вещи.
Первое. В файл /etc/postfix/main.cf
дописать строки ниже. Делать это нужно
под sudo
:
relayhost = [smtp.gmail.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_use_tls = yes
smtp_sasl_mechanism_filter = plain
Второе. Создать файл /etc/postfix/sasl_passwd
и вписать в него:
[smtp.gmail.com]:587 username@gmail.com:password
, где password
— пароль приложения для почты. Сгенерить этот пароль можно на
специальной странице Гугла.
Замечу, что вместо gmail.com
может быть ваш домен, если он нацелен на гугловые
сервера как в моем случае.
Третье — указать postfix
новые конфиги и перезагрузить его:
sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd
sudo launchctl stop org.postfix.master
sudo launchctl start org.postfix.master
Все. Пробуем отправить письмо. Сообщим в нем содержимое домашней папки:
ls -l | mail -s 'my home dir' ivan@grishaev.me
Мне пришло с первого раза. Plain text, красота.
Так вот, теперь когда почта работает, настроим крон. Открываем его командой
crontab -e
и пишем сверху:
MAILTO=<ваша@почта>
Кроме того, в конец каждой команды добавляем эхо, например:
0 */3 * * * cd /some/path && command --foo 42 && echo OK
Зачем нужно эхо? Оказалось, что крон не отправляет письмо, если выхлоп задачи
пуст. А поскольку я всегда хочу знать о запуске задачи, то делаю вывод не
пустым. Вместо echo OK
можно вывести текущую дату с помощью && date
.
В результате мы получим письмо, где тема — команда задачи, а тело — ее выхлоп. Работает в том числе и для задач, которые не сработали из-за ошибки.
Я уж не говорю о том, что с помощью mail
можно быстро что-то скидывать себе на
почту, организовать какие-то заметки и прочее. Что самое прекрасное — нет
интерфейса, все простое и открытое, работает везде. Чудо.
В следующий раз расскажу, что именно я ставлю на крон, там тоже интересные вещи.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter
Антон, 23rd Jun 2021, link
Иван, а смотри, по моему опыту проблема в том что регулярно письма падают, глаз замыливается а в один день письмо не приходит, и это заметить сложнее, чем в обратной ситуации - когда по дефолту все ок, а в случае проблемы приходит письмо.
Я аналогичную проблему решал сервисом (ставили селфхостед, но можно обойтись и SaaS, бесплатным аккаунтом) - https://healthchecks.io/
Ivan Grishaev, 24th Jun 2021, link , parent
Пока не заметил замыливания глаза, там посмотрим.
Ivan Grishaev, 24th Jun 2021, link , parent
За ссылку спасибо, выглядит полезно.