Программирование

CRON. Планирование задач

Часто возникает потребность выполнить ту или иную задачу автоматически (скрипт выполнить, процесс запустить и т.п.) в определенный момент времени. Более того, бывают случаи когда эта самая задача должна выполняться несколько раз по определенному расписанию. Все эти задачи решает crontab.

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

Синтаксис команды crontab следующий:

crontab [ -u user ] file
crontab [ -u user ] [ -i ] { -e | -l | -r }

Первая форма команды подразумевает установку таблицы из стороннего файла или стандартного потока ввода. Вторая форма более гибкая, имеет следующие флаги:

  • -u user — имя пользователя, чью крон-таблицу следует использовать для дальнейшей работы команды. Если не задано, то используется тот пользователь, который запускает команду crontab;
  • -l — вывести текущую крон-таблицу в стандартный поток вывода;
  • -r — удалить текущую крон-таблицу;
  • -e — отредактировать текущую крон-таблицу. После выхода из редактора, измененная крон-таблица будет проверена на ошибки автоматически;
  • -i — дополняет опцию -r дополнительным запросом к пользователю перед удалением крон-таблицы.

ВНИМАНИЕ! При использовании только опции -r удаление крон-таблицы происходит без каких-либо дополнительных подтверждений!

Каждая крон-таблица содержит инструкции, которые можно выразить в следующей форме: выполни определенную команду в определенное время определенного дня. Каждая команда в отдельно взятой крон-таблице выполняется от имени пользователя, которому принадлежит данная таблица.

Необходимо быть осторожным при использовании команды crontab за другого пользователя и всегда указывать опцию -u user.

Крон-таблица может содержать следующие строки:

  • Комментарии. Строки, начинающиеся со знака « игнорируются. Комментарии не могут находиться на одной строке с переменными окружения или крон-командами, т.к. станут частью значения или команды соответственно.
  • Переменные окружения. Строка в формате ключ=значение. Пробелы вокруг знака «=» игнорируются, остальные (до символа новой строки \n) попадают в значение. Подстановки не поддерживаются, т.е. следующие пример работать НЕ будет: PATH = ~/bin:/usr/bin:/bin:$HOME;
  • Крон-команды. Содержит пять полей с датой/временем, после которых следует команда для выполнения. Каждая строка должна завершаться символом новой строки \n. Ниже показаны допустимые значения для полей с датой/временем.
ПолеДопустимые значения
Минуты0-59
Часы0-23
День месяца1-31
Месяц1-12
День недели0-7 (0 или 7 — воскресенье)

Команда выполняется когда минуты, часы, месяц и как минимум одно поле, определяющее день (день месяца или день недели), совпадут с текущей датой и временем.

Каждое поле может содержать специальный синтаксис:

  • * — все допустимые значения данного поля;
  • <число>-<число> — диапазон значений, которые включается как первое число, так и второе. Например, 8-11 для поля «часы» будет обозначать запуск команды в следующие часы: 8, 9, 10, 11;
  • <число>,<число> — несколько предопределенных значений;
  • <число>-<число>/<число> — диапазон значений с определенным шагом. Например, 0-12/2 для поля «часы» будет обозначать запуск команды в следующие часы: 0, 2, 4, 6, 8 ,10, 12.
    Данный синтаксис также доступен в следующем виде: */<число>.
  • Комбинированные значения из нескольких диапазонов. Например, 2,4,12-16/2 для поля «часы» будет обозначать запуск команды в следующие часы: 2, 4, 12, 14, 16.

Шестым полем крон-команды (до символа новой строки \n) является непосредственно запускаемая команда, которая будет передана оболочке /bin/sh или иной, которая была определена при помощи переменной окружения SHELL.

Не существует способа разделить одну команду на несколько строк.

Пример крон-таблицы

# использовать /bin/bash для запуска команд вместо /bin/sh
SHELL=/bin/bash
#
# запускать ежедневно в 00:05
5 0 * * *       $HOME/bin/daily.job >> $HOME/tmp/out 2>&1
# запускать ежемесячно 1 числа в 02:15
15 14 1 * *     $HOME/bin/monthly.job
# запускать в 22:00 с понедельника по пятницу
0 22 * * 1-5    $HOME/bin/weekdays.job
23 0-23/2 * * * echo "запускать каждые 2 часа ежедневно, начиная с 00:23"
5 4 * * 7       echo "запускать каждое воскресенье в 05:04"
0 */4 1 * 1     echo "запускать каждый 4 час каждого первого числа, либо по понедельникам"
0 0 */2 * 0     echo "запускать в полночь либо по четным дням, либо по воскресеньям"

Полезные ссылки

  • https://crontab.guru/ — быстрый и простой редактор крон-выражений