Linux: cron, crontab, at, atd

Общее

  • В docker image может отсутствовать cron и даже редактор для управления
apt install cron
apt install vim
  • Про at, atd подробнее в конце статьи отдельный раздел (включая список литература), в целом статья про cron
  • Крутой мануал на русском по настройке CronTab, большая часть ин-ии оттуда
  • Wiki помимо теории есть пример настройки
  • Используя файлы cron.allow и cron.deny в директории /etc/ или /etc/cron.d можно управлять доступом к команде cron. Если есть cron.allow – доступ разрешен только пользователям из allow, если deny – запрещен тем, кто там, а если бы не было обоих файлов – только root. По умолчанию в большинстве дистрибутивов есть только файл deny, но в debian нет обоих файлов https://manpages.debian.org/unstable/cron/crontab.1.en.html
These access control files work together as follows:
- If cron.allow exists, only the users who are listed in this file can create, edit, display, or remove crontab files.
-If cron.allow does not exist, all users can submit crontab files, except for users who are listed in cron.deny.
-If neither cron.allow nor cron.deny exists, superuser privileges are required to run the crontab command.
No default cron.allow file is supplied.
So, after Oracle Solaris software installation, all users (except users who are listed in the default cron.deny file) can access the crontab command. If you create a cron.allow file, only these users can access the crontab command.
  • Даже приложения типа cacti используют cron для своей работы (переодический запуск опросчика и рисователя)
Из установки Cacti:
9) Создаём задание в кроне
crontab -e
*/5 * * * * php /var/www/cacti/poller.php > /dev/null 2>&1

cron — демон-планировщик задач в UNIX-подобных операционных системах, использующийся для периодического выполнения заданий в определённое время. Регулярные действия описываются инструкциями, помещенными в файлы crontab.

Предположим нам нужно запускать определенную задачу каждый день, или, может, каждую субботу в 12 ночи? В Unix-подобных системах существует возможность автоматизировать запуск повторяющихся задач при помощи демона планировщика задач cron.

Ключи

Для управления планировщиком задач обычно используется команда crontab со следующими ключами:

    • crontab -l – показывает список текущих задач.
    • crontab -e – запускает редактор планировщика задач для редактирования файла crontab вашего пользователя. Тут можно создавать задания. Редактор берется из переменной EDITOR, я предпочитаю для crontab VIM, поэтому даже на системах где EDITOR выставлен другой, перед crontab -e устанавливаю его в VIM через export EDITOR=vim. Нужно учесть, что запись файла через команду w без выхода wq из режима редактирования не приведет к установке нового crontab, установка происходит только после выхода из файла.
    • crontab -r – удаляет все текущие задачи.
    • crontab -u <username> – определяет пользователя, чьи задачи будут просматриваться/редактироваться, отсутствие данного параметра устанавливает текущего пользователя.
[root@localhost ~]# sudo crontab -u user3 -l
no crontab for user3
[root@localhost ~]# sudo crontab -u user3 -e

Таким образом, для назначения определенной задачи нужно выполнить команду crontab -e и построчно написать список необходимых задач на основе синтаксиса cron.

В некоторых случаях crontab отсутсвует в системе, но при этом сам cron вполне себе присутствует. Управление в таком случае может осуществляться напрямую в пользовательских файлах без использования crontab, напр. по пути:

/var/spool/cron/crontabs/root  # for root
/var/spool/cron/crontabs/user  # for user

Синтаксис

    • https://crontab.guru/ – Очень удобный сайт с примерами и возможностью подбора синтаксиса

В общем виде задача крон представляет собой строку вида:

* * * * * команда

Каждой звездочке в строке соответствует определенное значение:

*                  *             *                *              *                        команда
Минута (0-59)     Час (0-23)    День (1-31)     Месяц (1-12)    День недели (0-7)      Строка выполняемой команды

0 и 7 в дне недели обозначает воскресенье, поскольку в некоторых странах день недели начинается с воскресенья. Соответственно 1 – понедельник, 6 – суббота. В файле crontab помимо перечисленных выше допустимы следующие основные символы:

# - комментарий  (строки, начинающиеся с данного символа, не выполняются);
, - перечисление значений (1,2,3,4);
*/ - каждые n раз (*/n - каждые n, */5 - каждые 5, */2 - каждые 2);
- - интервал значений (1-5 - с 1 до 5, 4-6 - с 4 до 6).

Примеры настройки расписания

    • https://crontab.guru/ – Очень удобный сайт с примерами и возможностью подбора синтаксиса

Из вышеперечисленного следует, что следующие записи соответствуют следующим строкам:

МИНУТЫ
*/10 * * * * /home/www/myscript.php - каждые 10 минут;
24 * * * * /home/redkin/bin/script.sh - запускаемся каждую 24 минуту нового часа, полезно при тестах - ставишь на минуту-две позже текущего времени и смотришь отработку.

ДНИ
0 5 * * * /usr/bin/certbot renew --quiet - каждый день в 5:00 запускаем обновление TLS сертификата используя certbot
0 1 */1 * * /home/redkin/bin/exp_backup_daily_cacti – каждый день в 01:00
5 4 */7 * * /home/www/myscript.php - запуск задания каждые 7 дней в 4:05.

ДНИ НЕДЕЛИ
5 4 * * 1 /home/www/myscript.php - каждый понедельник в 4:05.
0 9 * * 1,3,5 /home/www/myscript.php - понедельник, среду и пятницу в 9 утра;
45 6 * * 1-5 /home/user/beep.sh - в 6:45 каждый рабочий день
0 18 * * 1-5 echo "Приезжай домой, Хозяин" | mail -s "Конец рабочего дня" user  - в конце каждого рабочего дня отсылается сообщение о том, что пора домой

МЕСЯЦЫ
0 2 1 * * /home/www/myscript.php - каждое 1-е число месяца в 02:00

ГОДЫ
0 2 1 1 * /home/www/myscript.php - 1 января каждого года в 02:00

Так же в файле crontab можно записывать следующие предопределенные значения:

@reboot - приветствие при каждой загрузке системы;
         @reboot echo 'Привет, Хозяин!'
@yearly - каждый год в полночь 1-го января;
         @yearly echo 'С Новым годом' - поздравление с новым годом каждый год в полночь 1-го января;
@monthly - каждый месяц в полночь 1-го числа;
@weekly - в полночь каждый понедельник;
@daily - ежедневно в 0:00;
         0 0 */1 * * /home/redkin/bin/exp_backup_daily_cacti
@hourly - в начале каждого часа.
         0 */1 * * * /home/redkin/bin/exp_backup_daily_cacti

Настройки системы

Стандартные настройки Cron включают объявление переменных. Это нужно для множества вещей – например установки кодировки, определения пути к файлу tnsnames.ora для Oracle или просто чтобы не ругался на ошибки неполного пути (самая частая ошибка когда скрипт из консоли запускается, но по cron нет, в противном случае нужно путь для многих утилит искать через whereis), отсылал все ошибки на твою почту, а не на учетную запись типа <user>@domain (очень полезно).

SHELL=/bin/bash 
PATH=/home/redkin/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
HOME=/home/redkin
MAILTO="petr@redkin.net"
LC_CTYPE=en_US.UTF-8

В противном случае в syslog (мы пробовали отправить письмо, но mail-сервер выдает ошибки т.к. такого пользователя нет):

Sep 24 23:30:02 server sSMTP[15981]: RCPT TO:<cacti@corbina.ru> (550 cacti@corbina.ru unknown user account)

Так же может понадобиться объявление дополнительных переменных, например, для работы Oracle-клиента.

LD_LIBRARY_PATH=/usr/lib/oracle/12.1/client64/lib:$LD_LIBRARY_PATH
NLS_LANG=RUSSIAN_CIS.UTF8

В случае если для какого-то скрипта нужно эти переменные будет поменять прописываем это в строчке со скриптом

NLS_LANG=RUSSIAN_CIS.CL8MSWIN1251; /home/redkin_p/bin/check_tt.rb

Ошибки

Если cron не работает – в первую очередь проверяем включен ли сервис (в зависимости от ОС), у меня в контейнере по умолчанию не включался, поэтому и не работал 🙂

service cron status
service crond status
systemctl status cron
ps -aux | grep cron
root 7837 0.0 0.0 3728 856 ? Ss 19:25 0:00 /usr/sbin/cron

Пример:
# service cron status
[FAIL] cron is not running ... failed!

Включаем и добавляем автозапуск:

service cron start
systemctl enable cron
update-rc.d cron defaults

# service cron start
[ ok ] Starting periodic command scheduler: cron.
root@35c4810c1e60:/var/www/html#
# service cron status
[ ok ] cron is running.

Логи запуска/отработки скриптов по крону хранятся в (так же зависит от ОС):

/var/log/syslog
/var/log/cron.log

Логи ошибок скриптов по крону по умолчанию приходят на почту локального пользователя (лучше задать конкретную почту – см. выше), но можно редиректить по стандарту все логи при запуске скрипта в отдельный файл. Я так делал, например, когда логи ошибок очень большие , по каким то причинам регулярные (привет, cacti!), на почте нет желания их хранить, но и в /dev/null не хочется их дропать.

0 0 */1 * * /home/redkin/bin/exp_backup_daily_cacti &>/home/redkin/log
24 * * * * /home/redkin/bin/script.sh - запускаемся каждую 24 минуту нового часа, полезно при тестах - ставишь на минуту-две позже текущего времени и смотришь отработку.

Если выдает ошибку Jan 28 12:25:01 server cron[24090]: Неизвестный модуль, то может помочь простой рестарт cron. Особенно если это после обновления. Обычно в качестве имени нужно указать cron или crond, в gentoo делается через vixie-cron.

sudo /etc/init.d/cron restart
sudo /etc/init.d/crond restart
sudo /etc/init.d/vixie-cron restart

 

AT/ATD

manual

install

apt install at
service atd status

use

# at 20:24 -f /root/test.sh # run
    warning: commands will be executed using /bin/sh
    job 1 at Thu Jan 28 20:24:00 2021

# at -c 1 # info about job

Leave a Reply