Введение / Зачем это нужно
Systemd-таймеры — это современный механизм планирования задач в системах, использующих systemd (практически все актуальные дистрибутивы Linux). Он пришел на смену классическому cron, предлагая более тесную интеграцию с системой инициализации, расширенные возможности расписания и единый журнал событий (journalctl). С помощью таймеров вы можете автоматизировать резервное копирование, очистку логов, проверку обновлений или запуск любых скриптов по расписанию, с задержкой после загрузки или даже в зависимости от других событий системы.
После прохождения этого гайда вы сможете создавать надежные и легко управляемые задания, которые будут корректно обрабатывать пропущенные запуски (например, если компьютер был выключен) и предоставлять детальную информацию о своих работах.
Требования / Подготовка
- Система с systemd: Убедитесь, что в вашем дистрибутиве используется systemd (проверьте
echo $INIT_SYSTEMилиps -p 1 -o comm=). - Права суперпользователя (root): Для создания системных юнитов в
/etc/systemd/system/и их управления требуются права администратора. Для пользовательских таймеров (без sudo) используйте~/.config/systemd/user/. - Базовое понимание systemd: Желательно знать, что такое unit-файлы и команда
systemctl. - Текстовый редактор: Например,
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
Задание будет запущено в случайный момент в течение часа после полуночи.
Проверка результата
- Убедитесь, что таймер активен:
systemctl is-active home-backup.timerдолжен вернутьactive. - Проверьте расписание:
systemctl list-timers | grep home-backupпокажет время следующего запуска. - Дождитесь срабатывания (или запустите вручную
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).