Автоматизация задач: cron и systemd timers

TIP

Эта статья — часть серии Linux administration, посвящённой самостоятельному администрированию Linux, Self-Hosting и DevOps. Автоматизация — основа эффективного управления инфраструктурой. cron и systemd timers позволяют выполнять задачи по расписанию без вашего участия.

📌 О чём эта статья?

Регулярные задачи — часть жизни любого сервера:

  • Резервное копирование
  • Обновление системы
  • Очистка временных файлов
  • Перезапуск сервисов
  • Отправка отчётов

В этой статье вы узнаете:

  • Как использовать классический cron
  • Как настроить современные systemd timers
  • Преимущества и недостатки каждого подхода
  • Практические примеры: бэкап, очистка, мониторинг
  • Лучшие практики и диагностика

🧩 Что такое автоматизация задач в Linux?

Linux предоставляет два основных механизма для запуска задач по расписанию:

  1. cron — классический демон, работающий с 1970-х
  2. systemd timers — современная альтернатива, интегрированная в systemd

Оба позволяют выполнять команды или скрипты в заданное время.

INFO

Выбор между ними зависит от дистрибутива, сложности задачи и требований к логированию и надёжности.


cron — классический планировщик

cron — самый известный инструмент для автоматизации. Работает через демон crond.

🔹 Как работает?

Каждый пользователь (включая root) имеет свой crontab — файл с расписанием.

Формат строки:

минута час день_месяца месяц день_недели команда
ПолеДиапазон
минута0–59
час0–23
день месяца1–31
месяц1–12
день недели0–7 (0 и 7 = воскресенье)

NOTE

Используйте * для “любое значение”.


🔹 Основные команды

crontab -e                    # Редактировать свой crontab
crontab -l                    # Просмотреть текущие задачи
crontab -r                    # Удалить все задачи (осторожно!)
sudo crontab -e               # Редактировать crontab root

🔹 Примеры

# Каждую минуту
* * * * * /home/alice/script.sh
 
# Каждый день в 2:30 утра
30 2 * * * /usr/local/bin/backup.sh
 
# Каждый понедельник в 6:00
0 6 * * 1 /usr/bin/apt update && /usr/bin/apt upgrade -y
 
# Каждый час
0 * * * * /usr/bin/certbot renew --quiet
 
# Раз в 5 минут
*/5 * * * * /usr/local/bin/check-service.sh

🔹 Где хранятся crontab’ы?

  • /var/spool/cron/crontabs/username — пользовательские (Debian/Ubuntu)
  • /var/spool/cron/username — RHEL/Fedora
  • /etc/crontab — системный crontab (с указанием пользователя)
  • /etc/cron.d/ — дополнительные задачи от пакетов

INFO

В /etc/crontab и /etc/cron.d/ формат:
мин час день мес день_недели ПОЛЬЗОВАТЕЛЬ команда


🔹 Переменные окружения

cron использует минималистичное окружение. Лучше указывать явно:

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=admin@selfops.dev

WARNING

Если скрипт использует переменные ($HOME, $PATH), указывайте полные пути.


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

Вместо первых пяти полей расписания можно использовать следующие строки:

  • @reboot – выполнить один раз после перезагрузки.
  • @yearly или @annually – выполнить один раз в год.
  • @monthly – выполнить один раз в месяц.
  • @weekly – выполнить один раз в неделю.
  • @daily или @midnight – выполнить один раз в день.
  • @hourly – выполнить один раз в час.

Важные замечания:

  • Всегда указывайте полный путь к командам, чтобы обеспечить их правильное выполнение, независимо от переменной PATH.
  • Специальные символы оболочки, такие как каналы (|) и перенаправления (>), работают должным образом в командах cron.
  • Переменная MAILTO в /etc/crontab определяет пользователя, которому будет отправлен отчет о выполнении расписания.

🕒 systemd timers — современная альтернатива

Systemd — это современная система инициализации и управления службами в Linux, фактически вытеснившая традиционную подсистему init. Она используется во многих современных дистрибутивах, таких как Fedora, Ubuntu, CentOS и openSUSE. Systemd включает концепцию таймеров, которые активируют заданные службы systemd по предопределенному расписанию. Таймеры systemd считаются более мощными, чем записи crontab, хотя и сложнее в настройке и управлении.

🔹 Основные функции systemd-таймеров:

  • Интенсивное распараллеливание запуска служб в процессе загрузки системы, что ускоряет ее запуск.
  • Активация на основании сокетов, устройств, d-bus или путей, что позволяет запускать службы только при необходимости, экономя ресурсы.
  • Обратная совместимость с SysV init, хотя современные пакеты служб уже адаптированы под systemd.

🔹 Преимущества перед cron:

  • Лучшая интеграция с systemd
  • Поддержка запуска после спящего режима (Persistent=true)
  • Точное время выполнения
  • Автоматическое логирование в journalctl
  • Возможность запуска как пользовательских, так и системных юнитов

🔹 Структура: .service + .timer

Таймер systemd состоит из двух файлов:

  1. mytask.service — что запускать
  2. mytask.timer — когда запускать Эти файлы обычно хранятся в каталоге /etc/systemd/system/

🔹 Пример: ежедневная очистка /tmp

1. Создаём службу: /etc/systemd/system/clean-tmp.service

[Unit]
Description=Очистка /tmp
Documentation=man:tmpfiles.d(5)
 
[Service]
Type=oneshot
ExecStart=/usr/bin/find /tmp -type f -atime +7 -delete

2. Создаём таймер: /etc/systemd/system/clean-tmp.timer

[Unit]
Description=Запуск очистки /tmp раз в день
Requires=clean-tmp.service
 
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=1h
 
[Install]
WantedBy=timers.target

3. Активируем

sudo systemctl daemon-reload
sudo systemctl enable clean-tmp.timer
sudo systemctl start clean-tmp.timer

🔹 OnCalendar — расписание

ЗначениеОписание
dailyКаждый день в 00:00
hourlyКаждый час
weeklyКаждую неделю
monthlyКаждый месяц
*-*-* 03:00:00Каждый день в 3:00
Mon,Fri *-*-* 06:00:00Пн и Пт в 6:00
*-1,-2,-3 *-*-* 02:00:001, 2, 3 числа каждого месяца

INFO

Поддерживает сложные выражения. Документация: man systemd.time


🔹 Другие полезные опции

ОпцияОписание
Persistent=trueЕсли система была выключена — запустить при включении
RandomizedDelaySec=1hСлучайная задержка до 1 часа (полезно для кластеров)
AccuracySec=1minТочность срабатывания
Unit=myservice.serviceКакую службу запускать (если имя не совпадает)

🔹 Управление и диагностика

systemctl list-timers                    # Список активных таймеров
systemctl list-timers --all              # Все таймеры (включая неактивные)
systemctl status mytask.timer            # Статус таймера
journalctl -u mytask.service             # Логи выполнения

🔁 Сравнение: cron vs systemd timers

Критерийcronsystemd timers
Простота✅ Очень простой⚠️ Требует двух файлов
Интеграция с systemd✅ Полная
Запуск после простоя✅ (Persistent=true)
ЛогированиеЧерез syslog или MAILTO✅ В journalctl
Гибкость расписания✅ (*/5, сложные шаблоны)✅ (OnCalendar)
Пользовательские таймеры✅ (crontab -e)✅ (systemctl --user)
Распространённость✅ Повсеместно✅ В системах с systemd

TIP

Используйте cron для простых задач.
Используйте systemd timers для сложных, критичных или интегрированных с системой задач.


🧪 Практические примеры

Пример 1: Ежедневный бэкап с cron

# crontab -e
0 2 * * * /usr/local/bin/backup-website.sh >> /var/log/backup.log 2>&1
#!/bin/bash
# /usr/local/bin/backup-website.sh
rsync -avz --delete /var/www/ backup@remote:/backups/www/

Пример 2: Обновление системы с systemd timer

/etc/systemd/system/update-system.service

[Unit]
Description=Обновление системы
After=network.target
 
[Service]
Type=oneshot
ExecStart=/usr/bin/apt update
ExecStart=/usr/bin/apt upgrade -y

/etc/systemd/system/update-system.timer

[Unit]
Description=Еженедельное обновление
Requires=update-system.service
 
[Timer]
OnCalendar=weekly
Persistent=true
 
[Install]
WantedBy=timers.target

Активация:

sudo systemctl daemon-reload
sudo systemctl enable update-system.timer

Пример 3: Пользовательский таймер

# Для пользователя
systemctl --user enable my-timer.timer

Полезно для:

  • Синхронизации с облаком
  • Регулярных уведомлений
  • Фоновых скриптов

INFO

Требует loginctl enable-linger $USER для автозапуска без входа в систему.


⚠️ Лучшие практики

  1. Всегда тестируйте скрипты вручную перед добавлением в расписание.
  2. Логируйте выполнение:
    */5 * * * * /script.sh >> /var/log/script.log 2>&1
  3. Используйте полные пути к командам (/usr/bin/rsync, а не rsync).
  4. Настройте MAILTO в crontab, чтобы получать уведомления об ошибках.
  5. Не запускайте тяжёлые задачи в пиковой нагрузке.
  6. Используйте RandomizedDelaySec в systemd timers для распределения нагрузки.

📊 Диагностика и проверка

# Проверить, запускался ли таймер
systemctl status mytimer.timer
 
# Посмотреть логи службы
journalctl -u mytask.service -b
 
# Проверить синтаксис crontab
crontab -l | cat  # просто проверить, нет ли ошибок
 
# Узнать, когда сработает таймер
systemctl list-timers
 
# Проверить, работает ли демон cron
systemctl status cron   # или crond

Сравнение и рекомендации:

  • Cron является традиционным, простым в использовании для базовых, периодических задач и личных скриптов.
  • Systemd-таймеры — это более современное и мощное решение, тесно интегрированное с systemd, предлагающее улучшенное управление зависимостями, параллельное выполнение и более легкую отладку. Они предпочтительнее для сложных системных задач в современных дистрибутивах Linux.
  • При отладке запланированных задач рекомендуется проверять обе системы, поскольку программные пакеты могут добавлять свои задания в любую из них.
  • Для автоматического резервного копирования rsync в сочетании с cron или systemd-таймерами является распространенной и эффективной стратегией.
  • Избегайте одновременного запуска одних и тех же команд на сотнях машин с помощью cron, чтобы предотвратить сетевые сбои; используйте скрипты случайной задержки. Для systemd-таймеров это решается с помощью AccuracySec.

✅ Заключение

Теперь вы можете:

  • Настроить регулярные задачи с cron
  • Использовать современные systemd timers
  • Выбирать подходящий инструмент под задачу
  • Логировать и диагностировать выполнение

QUOTE

“Хороший администратор делает работу один раз.
Плохой — делает её каждый день.”