Перейти к основному содержимому

Crontab в Linux

·861 слово·5 минут
DevOps • Networks • Security • Infrastructure
Автор
DevOps • Networks • Security • Infrastructure
DevOps/Network/Infra Engineer, CyberSecurity Expert

cron — стандартный планировщик задач в Linux. С его помощью можно автоматически запускать команды и скрипты по времени: каждые несколько минут, каждый час, по дням недели или при загрузке системы.

Типичные задачи для cron: резервное копирование, очистка файлов, мониторинг, проверка сервисов, синхронизация и автоматический перезапуск служб.

Что такое cron и crontab
#

За выполнение заданий обычно отвечает служба cron. Проверить её состояние:

systemctl status cron

На некоторых дистрибутивах служба называется crond:

systemctl status crond

crontab — таблица заданий текущего пользователя.

Команда Назначение
crontab -e Редактировать задания
crontab -l Показать задания
crontab -r Удалить все задания
sudo crontab -e Редактировать задания root
sudo crontab -l Показать задания root

После сохранения crontab перезапускать cron не требуется.

Пример проверки сервиса через cron
#

Допустим, скрипт находится в /usr/local/bin/check-nginx.sh

#!/bin/bash

TAG="nginx-check"

if systemctl is-active --quiet nginx; then
    logger -t "$TAG" "nginx is running"
else
    logger -t "$TAG" "nginx is down, restarting"
    systemctl restart nginx
fi

Делаем его исполняемым:

chmod +x /usr/local/bin/check-nginx.sh

Запускаем каждые 15 минут:

*/15 * * * * /usr/local/bin/check-nginx.sh

Проверяем логи:

journalctl -t nginx-check

Формат crontab
#

* * * * * команда
│ │ │ │ │
│ │ │ │ └── день недели
│ │ │ └──── месяц
│ │ └────── день месяца
│ └──────── час
└────────── минута
Поле Значения
Минута 0-59
Час 0-23
День месяца 1-31
Месяц 1-12
День недели 0-7

Дни недели:

День Значение
Воскресенье 0 или 7
Понедельник 1
Вторник 2
Среда 3
Четверг 4
Пятница 5
Суббота 6

Например, запуск backup каждый день в 03:00:

0 3 * * * /usr/local/bin/backup.sh

Частые расписания
#

Когда запускать Crontab
Каждую минуту * * * * * command
Каждые 5 минут */5 * * * * command
Каждые 15 минут */15 * * * * command
Каждые 30 минут */30 * * * * command
Каждый час 0 * * * * command
Каждый день в 00:00 0 0 * * * command
Каждый день в 03:00 0 3 * * * command
Каждый день в 03:30 30 3 * * * command
Каждый понедельник в 09:00 0 9 * * 1 command
По будням в 09:00 0 9 * * 1-5 command
По выходным в 09:00 0 9 * * 6,0 command
Первого числа месяца 0 0 1 * * command
В 08:00, 12:00 и 18:00 0 8,12,18 * * * command
Каждые 15 минут с 08:00 до 18:59 */15 8-18 * * * command

Специальные значения
#

Значение Когда выполняется
@reboot При загрузке системы
@hourly Каждый час
@daily Каждый день
@weekly Каждую неделю
@monthly Каждый месяц
@yearly Каждый год

Например:

@reboot /usr/local/bin/script.sh

Абсолютные пути
#

Через SSH команда может работать:

docker ps

а через cron — нет, потому что окружение и PATH отличаются.

Узнать полный путь:

which docker

Например:

/usr/bin/docker

Тогда в cron лучше использовать:

*/5 * * * * /usr/bin/docker ps

Это касается docker, systemctl, ip, curl, rsync, python и других внешних команд.

При необходимости PATH можно задать прямо в crontab:

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

Логи
#

Перенаправить stdout и stderr в файл:

*/15 * * * * /usr/local/bin/script.sh >> /var/log/script.log 2>&1

Полностью отключить вывод:

*/15 * * * * /usr/local/bin/script.sh >/dev/null 2>&1

На этапе отладки лучше вывод не отключать.

Для логирования через journal можно использовать logger:

logger -t my-script "Script started"
Команда Назначение
journalctl -t my-script Все записи
journalctl -t my-script -n 50 Последние 50
journalctl -t my-script -f Смотреть в реальном времени

/etc/crontab - это системный файл расписания cron
#

crontab -e относится к конкретному пользователю, поэтому имя пользователя в строке не указывается:

*/15 * * * * /usr/local/bin/script.sh

В /etc/crontab есть дополнительное поле пользователя:

*/15 * * * * root /usr/local/bin/script.sh

Формат:

минута час день месяц день_недели пользователь команда

Проверка работы cron
#

Действие Команда
Проверить статус systemctl status cron
Запустить systemctl start cron
Включить автозапуск systemctl enable cron
Включить и запустить systemctl enable --now cron
Посмотреть журнал journalctl -u cron
Смотреть журнал journalctl -u cron -f

На Ubuntu события также могут попадать в /var/log/syslog:

grep CRON /var/log/syslog

Быстрая проверка
#

Добавьте временное задание:

* * * * * date >> /tmp/cron-test.log

Через несколько минут:

cat /tmp/cron-test.log

Если новые строки появляются, cron работает.

Защита от параллельного запуска
#

Если скрипт запускается каждые 5 минут, но выполняется дольше, может запуститься несколько экземпляров одновременно.

Для защиты используется flock:

*/5 * * * * /usr/bin/flock -n /run/backup.lock /usr/local/bin/backup.sh

С логированием:

*/5 * * * * /usr/bin/flock -n /run/backup.lock /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

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

Пример crontab
#

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

# Проверка маршрутов каждые 15 минут
*/15 * * * * /usr/bin/flock -n /run/ipsec-routing-check.lock /usr/local/sbin/ipsec-routing-check.sh

# Backup каждый день в 03:00
0 3 * * * /usr/local/bin/backup.sh

# Очистка временных файлов каждое воскресенье в 04:00
0 4 * * 0 /usr/local/bin/cleanup.sh

Если cron не работает
#

Что проверить Команда
Состояние службы systemctl status cron
Текущий crontab crontab -l
Crontab root sudo crontab -l
Запуск скрипта вручную /usr/local/bin/script.sh
Права на файл ls -l /usr/local/bin/script.sh
Сделать файл исполняемым chmod +x /usr/local/bin/script.sh
Логи cron journalctl -u cron
Логи скрипта journalctl -t script-name

Итог
#

cron — простой и надёжный инструмент автоматизации Linux. Для серверных задач лучше использовать абсолютные пути, писать логи, учитывать ограниченное окружение cron и применять flock, если нельзя допускать параллельный запуск нескольких экземпляров скрипта.

Related

Как изменить образ Docker
·561 слово·3 минут
Основные команды Docker
·1030 слов·5 минут
Простейший HTTP-сервер на Python
·163 слов·1 минута