← Весь справочник

cron и crontab

Запуск команд по расписанию — формат crontab, команды crontab -e/-l, системные файлы и ловушки окружения

cron — демон, который раз в минуту просыпается, читает расписания и запускает команды, чьё время пришло. Расписание пользователя — его crontab, его редактируют командой crontab. Есть и системные расписания в /etc/crontab и /etc/cron.d/.

Синтаксис

crontab -e            # редактировать своё расписание
crontab -l            # показать
crontab файл          # заменить расписание содержимым файла

Строка расписания:

# мин  час  день  месяц  день_недели  команда
  30   2    *     *      1-5          /usr/local/bin/report.sh

Поля

ПолеЗначения
минута0–59
час0–23
день месяца1–31
месяц1–12 или jan–dec
день недели0–7 (0 и 7 — воскресенье) или sun–sat
командавсё до конца строки; выполняется через /bin/sh
Запись в полеЗначение
*любое значение
5ровно 5
1,15список: 1 и 15
1-5диапазон: с 1 по 5 включительно
*/10каждое десятое: 0, 10, 20…
9-18/3шаг внутри диапазона: 9, 12, 15, 18

Специальные строки

СтрокаЭквивалент
@rebootодин раз при старте демона cron
@hourly0 * * * *
@daily / @midnight0 0 * * *
@weekly0 0 * * 0
@monthly0 0 1 * *
@yearly / @annually0 0 1 1 *

Команда crontab

ОпцияЧто делает
-eоткрыть расписание в редакторе ($VISUAL / $EDITOR); после сохранения синтаксис проверяется
-lвывести расписание; если его нет — «no crontab for …» и код 1
-rудалить всё расписание без вопросов; -ri — с подтверждением
файл / -установить расписание из файла / со stdin (старое заменяется целиком)
-n файлтолько проверить синтаксис, не устанавливать
-u пользовательработать с расписанием другого пользователя (нужен root)

Расписания пользователей хранятся в /var/spool/cron/crontabs/<имя>, но править их надо только через crontab.

Переменные в crontab

Строки вида ИМЯ=значение задают окружение для заданий ниже этой строки.

ПеременнаяЧто задаёт
PATHгде искать команды; по умолчанию только /usr/bin:/bin
SHELLчем выполнять команду; по умолчанию /bin/sh (это dash, не bash)
MAILTOкому отправлять вывод заданий; MAILTO="" — никому
HOMEдомашний каталог; задания стартуют в нём

Остальное окружение минимально: задание видит HOME, LOGNAME, PATH, SHELL, PWD, LANG и то, что ты задашь сам.

Системные расписания

ГдеОсобенность
/etc/crontabесть шестое поле — пользователь: 17 * * * * root команда
/etc/cron.d/<файл>тот же формат с пользователем; файл подхватывается без crontab
/etc/cron.hourly/, daily/, weekly/, monthly/исполняемые скрипты, которые запускает run-parts из /etc/crontab

Примеры

# установить расписание из файла и проверить
crontab jobs.txt
crontab -l

# проверить синтаксис, ничего не меняя
crontab -n jobs.txt

# добавить строку к существующему расписанию
(crontab -l 2>/dev/null; echo '0 3 * * * /usr/local/bin/backup.sh') | crontab -

# чужое расписание
crontab -u www-data -l

# cron должен быть запущен, иначе ничего не выполнится
service cron start
pgrep -x cron

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

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=""

# каждые 5 минут, вывод и ошибки — в лог
*/5 * * * * /usr/local/bin/check.sh >> /var/log/check.log 2>&1

# в 02:30 по будням
30 2 * * 1-5 /usr/local/bin/report.sh

# 1-го и 15-го числа в полночь
0 0 1,15 * * /usr/local/bin/invoice.sh

# процент в команде нужно экранировать
0 0 * * * tar czf /backup/etc-$(date +\%F).tgz /etc

# при старте cron
@reboot /usr/local/bin/warmup.sh

Подводные камни

  • PATH в cron — только /usr/bin:/bin. Команда из /usr/sbin или /usr/local/bin, которая работает в терминале, в cron даст «command not found». Пиши полные пути или задай PATH в начале crontab.
  • % в команде — это перевод строки. Всё после первого неэкранированного % уходит команде на stdin. date +%F в crontab сломается — пиши date +\%F.
  • Переменные действуют только на строки ниже. PATH=…, записанный после задания, на это задание не повлияет.
  • Последняя строка должна заканчиваться переводом строки. crontab такой файл не примет, а в /etc/cron.d последняя строка без \n молча игнорируется.
  • День месяца и день недели объединяются через «ИЛИ». 0 0 13 * 5 — это «каждое 13-е число и каждую пятницу», а не «пятница, 13-е».
  • Команда выполняется в sh, не в bash. [[ ]], {1..5}, &> не работают, пока не задан SHELL=/bin/bash.
  • Вывод заданий никуда не попадёт: cron пытается отправить его почтой, а почта в контейнере не настроена. Перенаправляй в файл: >> /var/log/job.log 2>&1.
  • В /etc/cron.d и /etc/crontab нужно поле пользователя. Без него cron примет первое слово команды за имя пользователя, и задание не выполнится.
  • Файлы в /etc/cron.d с точкой в имени (backup.cron) игнорируются, как и файлы, доступные на запись группе или всем. Имя — только буквы, цифры, - и _, права — 644.
  • В контейнере cron сам не запущен. Пока нет процесса cron, расписание не работает: service cron start. Изменения crontab демон замечает при ежеминутной проверке.
  • Время — по часовому поясу системы. В песочнице это UTC; проверь date.

См. также

date · service · redirection · logrotate