Linux

Systemd-таймеры: гибкая замена cron для автоматизации в Linux

В этом гайде вы научитесь использовать systemd-таймеры — современный и мощный механизм планирования задач в Linux, который предлагает больше возможностей, чем классический cron. Мы разберем создание юнитов, управление через systemctl и решение типичных проблем.

Обновлено 16 февраля 2026 г.
15-30 минут
Средняя
FixPedia Team
Применимо к:systemd 235+ (все современные дистрибутивы: Ubuntu 18.04+, Debian 9+, CentOS 7+, Fedora 25+)

Введение / Зачем это нужно

Systemd-таймеры — это современный механизм планирования задач в системах, использующих systemd (практически все актуальные дистрибутивы Linux). Он пришел на смену классическому cron, предлагая более тесную интеграцию с системой инициализации, расширенные возможности расписания и единый журнал событий (journalctl). С помощью таймеров вы можете автоматизировать резервное копирование, очистку логов, проверку обновлений или запуск любых скриптов по расписанию, с задержкой после загрузки или даже в зависимости от других событий системы.

После прохождения этого гайда вы сможете создавать надежные и легко управляемые задания, которые будут корректно обрабатывать пропущенные запуски (например, если компьютер был выключен) и предоставлять детальную информацию о своих работах.

Требования / Подготовка

  1. Система с systemd: Убедитесь, что в вашем дистрибутиве используется systemd (проверьте echo $INIT_SYSTEM или ps -p 1 -o comm=).
  2. Права суперпользователя (root): Для создания системных юнитов в /etc/systemd/system/ и их управления требуются права администратора. Для пользовательских таймеров (без sudo) используйте ~/.config/systemd/user/.
  3. Базовое понимание systemd: Желательно знать, что такое unit-файлы и команда systemctl.
  4. Текстовый редактор: Например, nano, vim или vi.

Шаг 1: Создаем файл службы (.service)

Таймер не выполняет команды напрямую. Он активирует файл службы (.service), который содержит инструкции по запуску вашей задачи. Начнем с него.

Давайте создадим простую службу для резервного копирования домашней директории. Сохраните этот конфиг как /etc/systemd/system/home-backup.service:

[Unit]
Description=Резервное копирование домашней директории
# Запускать службу только если доступна сеть (опционально)
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
# Команда, которую нужно выполнить. Пример с tar и сжатием.
ExecStart=/bin/tar -czf /var/backups/home_$(date +\%Y-\%m-\%d).tar.gz /home
# Указываем, что задание выполняется один раз за запуск таймера
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Ключевые моменты:

  • Type=oneshot: Процесс службы завершается после выполнения ExecStart. Используется для одноразовых задач.
  • ExecStart: Основная команда. Обратите внимание на экранирование % в date (нужно \%).
  • RemainAfterExit=yes: Позволяет службе считаться активной после завершения команды. Полезно для мониторинга статуса.
  • Если нужно выполнить несколько команд, используйте скрипт и укажите его путь в ExecStart, или через ExecStartPre/ExecStartPost.

Шаг 2: Создаем файл таймера (.timer)

Теперь создадим файл таймера, который будет запускать нашу службу по расписанию. Сохраните как /etc/systemd/system/home-backup.timer:

[Unit]
Description=Таймер для ежедневного резервного копирования домашней директории

[Timer]
# Расписание: каждый день в 02:30
OnCalendar=*-*-* 02:30:00
# Если задание было пропущено (компьютер выключен), запустить его при следующей загрузке
Persistent=true
# Служба, которую активировать
Unit=home-backup.service

[Install]
WantedBy=timers.target

Ключевые моменты:

  • OnCalendar=*-*-* 02:30:00: Гибкий синтаксис календаря. * означает "любое значение". Здесь: любой год, любой месяц, любой день в 02:30.
    • Примеры: Mon *-*-* 09:00:00 (каждый понедельник в 9 утра), *-*-1 00:00:00 (в первый день каждого месяца).
  • Persistent=true: Критически важная опция! Если компьютер был выключен в момент срабатывания таймера, systemd запустит задание сразу же при следующей загрузке системы.
  • Unit=home-backup.service: Явно указываем, какую службу запускать. Если имя файла службы совпадает с именем таймера (например, home-backup.timer и home-backup.service), этот параметр можно опустить.

Шаг 3: Перезагружаем конфигурацию systemd

После создания обоих файлов необходимо сообщить systemd о их существовании. Выполните команду:

sudo systemctl daemon-reload

Эта команда заставляет systemd перечитать все конфигурационные файлы. Без нее новые таймеры и службы не будут видны системе.

Шаг 4: Активируем и запускаем таймер

Теперь нужно включить таймер (чтобы он запускался автоматически при загрузке) и, возможно, запустить его сразу для теста.

# 1. Включить автозапуск таймера при загрузке системы
sudo systemctl enable home-backup.timer

# 2. Запустить таймер немедленно (для проверки)
sudo systemctl start home-backup.timer

# 3. Проверить статус
sudo systemctl status home-backup.timer

Вы должны увидеть активный (active (waiting)) таймер и время следующего запуска (Next elapse).

Шаг 5: Мониторинг и управление

Просмотр всех активных таймеров

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

systemctl list-timers

Эта команда покажет вам таблицу с именем таймера, временем следующего запуска, временем последнего запуска и юнитом, который он активирует.

Просмотр логов

Все, что выводит ваша служба (включая ошибки), попадает в журнал systemd. Для просмотра используйте journalctl:

# Логи конкретного таймера и связанной с ним службы
sudo journalctl -u home-backup.timer -u home-backup.service -f

# Логи за последний день
sudo journalctl -u home-backup.service --since "1 day ago"

Остановка и отключение

  • Остановить текущий запуск (если он в процессе): sudo systemctl stop home-backup.timer
  • Остановить и отключить автозапуск: sudo systemctl disable --now home-backup.timer

Шаг 6: Расширенные возможности и примеры

Запуск с задержкой после загрузки

Если задача должна запускаться не по календарю, а через некоторое время после загрузки системы (например, чтобы дать время на запуск сетевых служб), используйте OnBootSec:

[Timer]
OnBootSec=15min
Unit=home-backup.service

Это запустит службу через 15 минут после загрузки. Можно комбинировать: OnBootSec=5min и OnUnitActiveSec=1h для запуска через 5 минут после загрузки и затем каждый час.

Периодический запуск (интервал)

Для интервалов, не привязанных к календарю (например, "каждые 30 минут"), используйте OnUnitActiveSec:

[Timer]
OnUnitActiveSec=30min
Unit=home-backup.service

Это означает: запускать службу каждые 30 минут после последнего успешного запуска этой службы.

Случайный (рандомизированный) запуск

Чтобы избежать "шторма" при одновременном запуске множества таймеров на многих машинах (например, для обновлений), добавьте RandomizedDelaySec:

[Timer]
OnCalendar=daily
RandomizedDelaySec=1h

Задание будет запущено в случайный момент в течение часа после полуночи.

Проверка результата

  1. Убедитесь, что таймер активен: systemctl is-active home-backup.timer должен вернуть active.
  2. Проверьте расписание: systemctl list-timers | grep home-backup покажет время следующего запуска.
  3. Дождитесь срабатывания (или запустите вручную sudo systemctl start home-backup.timer) и проверьте:
    • Файл бэкапа: ls -lh /var/backups/
    • Статус службы: systemctl status home-backup.service
    • Журнал: sudo journalctl -u home-backup.service --no-pager -n 20

Если бэкап создался и в логах нет ошибок — всё работает.

Возможные проблемы

Таймер не запускается по расписанию

  • Проверьте синтаксис OnCalendar. Используйте systemd-analyze calendar '*-*-* 02:30:00' для валидации.
  • Убедитесь, что Persistent=true установлено, если компьютер может быть выключен в момент запуска.
  • Проверьте, не конфликтует ли таймер с cron. Systemd и cron независимы. Если задача уже есть в cron, отключите её, чтобы избежать двойного запуска.

Служба, запущенная таймером, завершается с ошибкой

  • Смотрите логи journalctl -u <service>.service. Ошибка почти всегда в команде ExecStart (неверный путь, нет прав, недостаточно места).
  • Проверьте права доступа к скрипту/команде и к целевым директориям/файлам. Для системных служб часто требуется root.
  • Убедитесь, что Type=oneshot соответствует вашей задаче. Если команда запускает демон, может потребоваться Type=forking или Type=notify.

Таймер не виден в systemctl list-timers

  • Выполнили ли вы daemon-reload после создания файлов?
  • Файлы имеют правильные имена и расположение? Для системных юнитов: /etc/systemd/system/<name>.timer. Для пользовательских: ~/.config/systemd/user/.
  • Таймер включен? sudo systemctl enable <name>.timer (для системного) или systemctl --user enable <name>.timer (для пользовательского).
  • Проверьте, не активирован ли таймер сразу: systemctl status <name>.timer. Если он active (waiting), он работает. Если inactive (dead), возможно, его нужно запустить (start).

Часто задаваемые вопросы

В чем основное преимущество systemd-таймера перед cron?
Как проверить, что мой таймер работает?
Можно ли запускать таймер только при наличии сети?

Полезное

Понимание структуры: два юнита
Создание файла службы
Создание файла таймера
Перезагрузка конфигурации systemd
Активация и запуск таймера
Мониторинг и отладка