Ivan Grishaev's blog
Writing on programming, education, books and negotiations.
HomeAboutBookshelfRSS
ClojureEmacsPythonProgrammingInterviewVideo
Книга «Clojure на производстве»
Книга «Clojure на производстве», второй том
Crontab и отправка почты
Jun 23, 2021 programming, cron, mail
На днях столкнулся с проблемой. На моем ноуте крутится несколько 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/