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, если нельзя допускать параллельный запуск нескольких экземпляров скрипта.