cron — это стандартный планировщик задач в Linux. С его помощью можно автоматически запускать команды и скрипты:
- каждые несколько минут;
- каждый час;
- каждый день;
- по определённым дням недели;
- при загрузке системы.
Например, cron удобно использовать для:
- резервного копирования;
- очистки временных файлов;
- проверки состояния сервисов;
- запуска скриптов мониторинга;
- синхронизации файлов;
- перезапуска служб при определённых условиях.
В этой статье разберём, как пользоваться crontab на практике.
Что такое cron и crontab #
В Linux за выполнение задач по расписанию обычно отвечает служба cron.
Проверить её состояние можно командой:
systemctl status cron
На некоторых дистрибутивах служба называется crond:
systemctl status crond
crontab — это таблица заданий пользователя, которую читает cron.
Каждый пользователь может иметь собственный набор задач.
Открыть crontab текущего пользователя:
crontab -e
Посмотреть текущие задания:
crontab -l
Удалить все задания текущего пользователя:
crontab -r
После сохранения файла вручную перезапускать cron обычно не требуется. Изменения подхватываются автоматически.
Формат crontab #
Строка задания выглядит так:
* * * * * команда
│ │ │ │ │
│ │ │ │ └── день недели
│ │ │ └──── месяц
│ │ └────── день месяца
│ └──────── час
└────────── минута
Полный формат:
минута час день_месяца месяц день_недели команда
Диапазоны:
| Поле | Значения |
|---|---|
| Минута | 0-59 |
| Час | 0-23 |
| День месяца | 1-31 |
| Месяц | 1-12 |
| День недели | 0-7 |
Для дня недели:
0 или 7 — воскресенье
1 — понедельник
2 — вторник
3 — среда
4 — четверг
5 — пятница
6 — суббота
Частые расписания #
Каждую минуту:
* * * * * command
Каждые 5 минут:
*/5 * * * * command
Каждые 15 минут:
*/15 * * * * command
Каждые 30 минут:
*/30 * * * * command
Каждый час:
0 * * * * command
Каждый день в полночь:
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
По выходным:
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 command
Каждый час:
@hourly command
Каждый день:
@daily command
Каждую неделю:
@weekly command
Каждый месяц:
@monthly command
Каждый год:
@yearly command
Запуск скрипта #
Допустим, скрипт находится здесь:
/usr/local/bin/backup.sh
Делаем его исполняемым:
chmod +x /usr/local/bin/backup.sh
Запуск каждые 15 минут:
*/15 * * * * /usr/local/bin/backup.sh
Используйте абсолютные пути #
Через SSH команда может работать:
docker ps
а через cron — нет.
Причина обычно в другом PATH.
Узнать полный путь:
which docker
Например:
/usr/bin/docker
В cron лучше использовать:
*/5 * * * * /usr/bin/docker ps
То же касается команд:
systemctl
ip
curl
rsync
python
docker
PATH в crontab #
Можно явно указать окружение:
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Например:
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
*/15 * * * * /usr/local/bin/script.sh
Логи #
Записать stdout и stderr в файл:
*/15 * * * * /usr/local/bin/script.sh >> /var/log/script.log 2>&1
Где:
>>
добавляет вывод в файл.
А:
2>&1
перенаправляет ошибки туда же.
Отключить вывод #
Если лог не нужен:
*/15 * * * * /usr/local/bin/script.sh >/dev/null 2>&1
На этапе отладки лучше так не делать.
Логирование через journalctl #
В скрипте:
logger -t my-script "Script started"
Посмотреть записи:
journalctl -t my-script
Последние 50 записей:
journalctl -t my-script -n 50
Следить в реальном времени:
journalctl -t my-script -f
Пример проверки сервиса #
Скрипт:
#!/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
Cron:
*/15 * * * * /usr/local/bin/check-nginx.sh
Логи:
journalctl -t nginx-check
Root crontab #
Если скрипт выполняет:
systemctl restart ...
или другие действия, требующие root, лучше использовать:
sudo crontab -e
Тогда в самом скрипте sudo обычно не требуется.
Например:
*/15 * * * * /usr/local/sbin/check-service.sh
/etc/crontab #
crontab -e и /etc/crontab имеют разный формат.
В пользовательском crontab:
*/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
Логи самого cron #
Через journalctl:
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 минут, но иногда работает 10 минут:
*/5 * * * * /usr/local/bin/backup.sh
может одновременно запуститься несколько экземпляров.
Для защиты используется 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 -l
Или для 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.
Основные команды:
crontab -e
редактирование заданий текущего пользователя.
crontab -l
просмотр заданий.
sudo crontab -e
редактирование заданий root.
Базовый синтаксис:
минута час день_месяца месяц день_недели команда
Например, выполнение скрипта каждые 15 минут:
*/15 * * * * /usr/local/bin/script.sh
Для серверных скриптов желательно:
- использовать абсолютные пути;
- писать логи;
- учитывать ограниченное окружение
cron; - запускать системные операции из
root crontab; - использовать
flock, если нельзя допускать одновременный запуск нескольких экземпляров.
Для небольших административных задач этого обычно достаточно, чтобы получить простой и надёжный механизм автоматического выполнения команд.