Комментарии 45
Я бы ещё добавил, всегда использовать crontab -e и не редактировать файлы cron напрямую.
А для одноразовых задач использовать at.
а в чём преимущества редактирования через `crontab -e`?
проверка синтаксиса при выходе из редактора, с предложением исправить ошибки (аналогично visudo, vipw)
Возможность опечататься и написать "crontab -r" - и на старых системах снести cron-овский файлик к чертям =)
Ну, а если серьезно тоже редактирую через crontab -e
Cтоило бы еще добавить, например,
что существует системный файл crontab, о котором писалось, и пользовательские файлы (/var/spool/cron/crontabs) которые не предназначены для редактирования вручную, и именно для них придуман crontab -e, чтобы, в частности, отправлять сигнал основному процессу перечитать кронтабы; как обычному пользователю редактировать /etc/crontab тоже как-то осталось за кадром
что путь по-умолчанию устанавливается в /bin:/usr/bin ( /sbin отсутствует ); ну и вообще про работу с переменными окружения
про cron.allow / cron.deny
PATH=/home/you/.local/bin:/usr/local/bin:/usr/bin:/bin
а потом кто-нибудь положит в /home/you/.local/bin файл с именем ls и интересным содержимым, и заимеет доступ к серверу (при неблагоприятных обстоятельствах).
Такие пути надо добавлять в конец.
А не лучше в 22году использовать таймеры systemd?
Синтаксис у cron, намного проще. Добавить строчку в cron намного проще, чем в таймеры. Мало кто без Гугла сможет создать новый таймер. Таймеры удобно использовать для некоторых специфических задач, например, случайная задержка при выполнении задания
Как раз хотел добавить что крон запускает все задачи время которых настало одновременно, поэтому, если их много и это допустимо, то не лишним будет вставить перед запуском sleep на какое-то время, случайное, или раскидать вручную, иначе можно упереться в диск или проц, например.
Сгладить или уменьшить пиковую загрузку ресурсов ещё поможет запуск с nice.
В этом десятилетии лучшая практика cron — это использовать systemd timers.
curl -fLsS -o /dev/null
Понимаю, почему так делают, работая из командной строки. Но в скрипте не лучше ли использовать длинные опции:
curl --fail --location --silent --show-error --output /dev/null
Так есть шанс, что через пару месяцев получится прочитать этот однострочник сходу, не залезая в другой консоли в man.
Дополню: если процесс ничего не вывел, то письмо отправлено не будет. Поэтому я добавляю в конец `... && echo OK`, чтобы получить письмо при любом раскладе.
Чтобы получить при любом раскладе — лучше что-то вроде ... ; echo OK
.
При использовании &&
выполнение echo
произойдет только если предыдущая команда выполнилась успешно (с нулевым кодом возврата в большинстве систем).
Скрипт мог сломаться и вернуть 500 ошибок.
Имелись ввиду 500-е коды ответа, а не количество, не переводите то чего не понимаете в принципе.
Совет перенести все задачи в анакрон, по мне очень хорош. С понятным именем, с комментом. Выглядит как логротэйт, и понимается отлично.
Лучшая практика cron - не использовать его.
man systemd.timer
Я недавно озадачился мониторингом cron
задач с нескольких серверов, чтобы можно было в одном месте видеть статусы по всем. Нашёл Healthchecks:
По завершению очередной cron
задачи отправляется HTTP запрос через cURL в API сервиса - так сервис узнаёт о её выполнении. Есть оповещения по почте, webhook (то есть и Telegram, хотя присутствует и отдельный вариант), Slack и прочие.
Сервис доступен как на официальном сервере, так и для self-hosted установки (вот небольшая инструкция).
... но на современном сервере он пропускает все таймеры.
Что такое "современный сервер" и что значит "пропускает все таймеры"?
Healthchecks это просто REST API сервис, который принимает HTTP запросы, а отправляются они с серверов, на которых выполняются cron
задачи по расписанию. То есть вы говорите что у cron
'а на серверах есть проблемы с точностью запуска задач по расписанию? Или что Healthchecks не соответствует расписанию cron
и потому ожидает пингов от серверов в неправильное время?
Так или иначе, я пока ничего похожего не заметил. У меня несколько серверов в разных временных зонах, и со всех пинги приходят вовремя.
Современный сервер, это сервер, на котором одна из указанных ОС:
Centos/RHEL 7, 8
Debian 9, 10, 11
Ubuntu 16.04, 18.04, 20.04, 22.04
(и примерно соответствующие им другие ОС). Не современный сервер, к которому написанное не применимо: Centos 6, Debian 8, Ubuntu 14.04.
На всех этих серверах в качестве pid 1 запущен процесс systemd.
systemd поддерживает таймеры. man systemd.timer
Это современный метод запуска периодических задач. А крон уже никто не использует давно, кроме легаси кода и почитателей статей образца 2010 года и раньше о том, что слаще крона джоб нет.
TL;DR; на современном сервере большинство периодических задач запускается не кроном.
А крон уже никто не использует давно
Ну если вы всех остальных уже опросили, тогда выходит я один такой остался. У меня ни разу не было случая, чтобы cron
задача не отработала в назначенное время. Останусь пока на нём.
Кроме того, мой первый комментарий был больше не про cron
, а про мониторинг выполнения запланированных задач, что скорее всего применимо и к этим таймерам от systemd
.
TL;DR; на современном сервере большинство периодических задач запускается не кроном.
Периодических или системных периодических?
Если вы зайдёте на сервер, там будет пачка задач. Более того, если вы добавите их как локальный системный администратор, то они всё равно будут системными, потому что есть ещё systemctl --user, и там тоже могут быть таймеры.
Для меня системная задача — это та, которая обслуживание системы выполняет. К примеру, скачивать файлик вгетом — это не системная задача. Или папку домашнюю синхронизировать.
Дальше, синтаксис крона — это дата и команда. Синтаксис системд — это целый файл сочинять надо. Да ещё потом разбираться, куда там дату вписывать.
OnCalendar=daily
Супер сложно, да.
Правильно, в другой файл.
То есть вместо строки дата команда надо два файла писать. Да ещё с синтаксисом разбираться. И ради чего?
Например, ради того, чтобы задачи крона не складывались стопочкой из-за того, что предыдущая не успела отработать.
И чтобы можно было сделать list-timers и посмотреть когда следующая задача выполнится. И чтобы по задаче можно было сказать status и увидеть, выполнилась она или нет.
И чтобы не получить ситуацию, что cronjob стартанула до того, как запустились все её requirements на загрузке (или при шатдауне системы).
Это мы пока не обсуждали когда запускается задача crontab'а, если система sleep или shutdown на запланированное время.
да никто не спорит с тем, что таймеры в systemd решают существующие проблемы, которые не решаются в cron (или решаются с помощью кривых костылей).
только это никак не отменяет того факта, что для многих задач эти таймеры менее удобны, чем cron
На всех этих серверах в качестве pid 1 запущен процесс systemd.
Конкретно на Debian в качестве pid 1 прекрасно работает init.
Я понимаю что есть любители systemd, но не стоит объявлять это единственно возможным и верным вариантом.
Таймеры можно, особенно если надо поставить "сторожок" действий на событие не устанавливая inotifywite incron из перечисленного в статье. Но тогда лучше это в motd сразу и написать, вместо "уважайте жизнь других". Расписания там (пока ?) мало кто ищет, это нехорошо, по отношению к коллегам до и "после меня". И не смешивать, или - или. Но рисовать три файла на задачу вместо одного, в чём побудительный мотив?
судя по коментариям кому нибудь давно пора написать статейку по сравнению cron и systemd timers, особо вменяемого на русском языке ничего не гуглится, ну или я гуглить разучился.
Вот вроде -https://habr.com/ru/company/ruvds/blog/512868/? , мне по крайне мере помогло разобраться, но так и не понял почему лучше.
Cron — лучшие практики