Автоматизация задач с помощью cron и systemd таймеры
На Linux‑сервере множество задач требуют регулярного выполнения: например, резервное копирование данных, обновление ПО, очистка логов или проверка сервисов. Делать это вручную – долго и рискованно: можно пропустить срок или допустить ошибку.
Автоматизация с помощью cron и systemd таймеры решает эти проблемы: вы настраиваете задачу один раз – и система выполняет ее точно в срок. В статье разберем, как работать с обоими инструментами, сравним их возможности и выберем подходящий вариант для разных сценариев.
Что такое cron
cron – это стандартный планировщик задач в Linux и Unix-подобных системах. Он запускает команды и скрипты по расписанию: раз в минуту, каждый час, по определенным дням недели, в начале месяца и так далее.
С помощью cron можно автоматизировать повторяющиеся действия: создавать резервные копии, очищать временные файлы, запускать обновления, отправлять отчеты, проверять состояние сервисов. Пользователю не нужно запускать эти команды вручную – система делает это сама в указанное время. cron работает как фоновая служба. Она постоянно запущена в системе и проверяет расписание задач. Если текущее время совпадает с условием в расписании, cron выполняет нужную команду.
Как работает crontab
crontab – это файл с расписанием задач cron. В нем указывают, какую команду нужно выполнить и в какое время. У каждого пользователя может быть свой crontab, а системные задачи обычно хранятся отдельно в системных каталогах.
Открыть crontab текущего пользователя можно командой:
crontab -e
Откроется редактор, где можно добавить или изменить задачи. Если нужно посмотреть текущие записи, выполните:
crontab -l
Запись в crontab состоит из расписания и команды:
* * * * * команда
Поля читаются слева направо:
| Поле | Что означает | Пример |
|---|---|---|
| Минута | От 0 до 59 | 30 – на 30-й минуте |
| Час | От 0 до 23 | 2 – в 02:00 |
| День месяца | От 1 до 31 | 15 – 15-го числа |
| Месяц | От 1 до 12 | 6 – в июне |
| День недели | От 0 до 7 | 1 – понедельник, 0 или 7 – воскресенье |
Например, вы можете прописать:
30 2 * * * /home/user/script.sh
Задача будет запускаться каждый день в 02:30.
Звездочка * означает «любое значение». Поэтому запись:
* * * * * /home/user/script.sh
будет запускать скрипт каждую минуту.
Также вы можете задавать интервалы и списки значений. Например, чтобы команда выполнялась каждые 10 минут, введите:
*/10 * * * * /home/user/check.sh
Или можно быть ещё конкретнее: задать команду, которую будет выполнять скрипт в 09:00 с понедельника по пятницу:
0 9 * * 1-5 /home/user/workday.sh
Важно: cron запускает команды в ограниченном окружении. Переменные среды могут отличаться от тех, что доступны в обычном терминале. Поэтому в crontab лучше указывать полные пути к скриптам и программам, а вывод ошибок направлять в лог-файл:
0 3 * * * /home/user/backup.sh >> /home/user/backup.log 2>&1
Так проще понять, выполнилась задача или завершилась с ошибкой.
Практические задачи для cron: резервное копирование, очистка логов, обновления
Cron чаще всего используют для задач, которые нужно выполнять регулярно и без участия пользователя. Например, каждый день создавать резервную копию, раз в неделю чистить старые логи или запускать обновление пакетов ночью, пока сервер не нагружен.
Резервное копирование
Одна из самых частых задач для cron – автоматическое создание резервных копий – это может быть архив сайта, дамп базы данных, копия конфигурационных файлов или синхронизация данных на другой сервер.
Чтобы задать создание резервной копии каталога, можно выполнить:
0 2 * * * tar -czf /backup/site-$(date +\%F).tar.gz /var/www/site
Задача будет запускаться каждый день в 02:00 и создавать архив с датой в имени файла.
В crontab у символа % есть отдельное значение, поэтому в команде date +%F его обязательно нужно экранировать: +\%F.
Чтобы задать создание резервной копии базы данных MySQL, пропишите:
30 2 * * * mysqldump -u backup_user -p'password' database_name > /backup/database-$(date +\%F).sql
Лучше не хранить пароль прямо в crontab. Более безопасный вариант – вынести параметры подключения в отдельный конфигурационный файл и ограничить права доступа к нему.
Очистка логов
Логи помогают искать ошибки, но со временем они могут занять много места. Cron можно использовать для удаления старых файлов, если в системе не хватает стандартной ротации логов или нужно чистить отдельные каталоги приложения.
Если нужно удалить логи старше 30 дней, можно воспользоваться командой:
0 4 * * * find /var/log/myapp -type f -name "*.log" -mtime +30 -delete
Задача будет выполняться каждый день в 04:00.
Для начала лучше запустить команду без -delete, чтобы проверить, какие файлы попадут под удаление:
find /var/log/myapp -type f -name "*.log" -mtime +30
А уже потом добавить удаление.
Иногда вместо удаления удобнее очищать содержимое файла, не удаляя сам файл:
0 5 * * 0 truncate -s 0 /var/log/myapp/debug.log
Задача будет очищать файл debug.log каждое воскресенье в 05:00.
Для системных логов лучше использовать утилиту logrotate, а не писать собственные cron-задачи. Она может сжимать старые логи, хранить заданное количество архивов и работать с сервисами.
Обновления
Cron можно использовать для автоматического обновления пакетов. Это удобно для тестовых серверов, внутренних стендов и систем, где допустимы регулярные автоматические изменения.
Пример для Debian и Ubuntu:
0 3 * * 1 apt update && apt upgrade -y >> /var/log/apt-cron.log 2>&1
Задача будет запускаться по понедельникам в 03:00, обновлять список пакетов и устанавливать доступные обновления.
В случае с CentOS, AlmaLinux, Rocky Linux или Fedora команда будет выглядеть так:
0 3 * * 1 dnf upgrade -y >> /var/log/dnf-cron.log 2>&1
Будьте осторожны с автоматическими обновлениями. Некоторые пакеты могут перезапустить сервисы, изменить зависимости или потребовать дополнительной настройки. Для рабочих серверов часто безопаснее автоматически устанавливать только обновления безопасности, а крупные обновления выполнять вручную после проверки.
Если автоматизация касается не только пользовательских скриптов, но и системных служб, важен полный контроль над окружением. На VPS Linux с полным root-доступом от SpaceWeb можно самостоятельно настроить cron, systemd таймеры, права пользователей, логи и резервное копирование.
Что такое systemd таймеры
Systemd таймеры – это механизм запуска задач по расписанию в системах, где используется systemd. Они выполняют похожую роль, что и cron: позволяют запускать команды, скрипты и сервисы в нужное время или через заданный интервал.
Таймер systemd состоит из двух файлов:
my-task.timer
my-task.service
Файл .timer отвечает за расписание – когда запускать задачу, а .service описывает само действие – какую команду выполнить.
Например, таймер может запускать скрипт резервного копирования каждый день в 03:00. В этом случае .timer задает время запуска, а .service запускает сам скрипт.
Пример service-файла:
[Unit]
Description=Create backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
Пример timer-файла:
[Unit]
Description=Run backup every day
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
После настройки таймер нужно включить:
systemctl enable --now my-task.timer
Посмотреть активные таймеры можно командой:
systemctl list-timers
Systemd таймеры удобны тем, что хорошо встроены в систему. Их можно отслеживать через systemctl, проверять логи через journalctl, настраивать зависимости от других сервисов и запускать задачи не только по времени, но и после загрузки системы или через определенный интервал после предыдущего запуска.
Чем systemd timers отличаются от cron
Cron проще и привычнее: одна строка в crontab – и задача уже работает по расписанию. Для простых пользовательских задач – раз в день запустить скрипт или раз в час очистить временные файлы – его достаточно.
Systemd таймеры устроены сложнее: нужно создать два файла – .service и .timer. Зато они предлагают больше контроля над запуском задачи и лучше подходят для системных сценариев.
| Возможность | cron | systemd timers |
|---|---|---|
| Простая настройка | Да, достаточно записи в crontab | Нужно создать service и timer |
| Запуск по расписанию | Да | Да |
| Запуск после загрузки системы | Ограниченно | Да, через настройки systemd |
| Запуск пропущенной задачи после простоя | Не всегда удобно | Да, через Persistent=true |
| Логи выполнения | Нужно настраивать вручную | Доступны через journalctl |
| Управление задачей | Через crontab | Через systemctl |
| Подходит для пользовательских задач | Да | Да |
| Подходит для системных задач | Да, но это менее гибкий вариант | Да |
Таким образом, главное отличие в том, что cron просто запускает команду по расписанию, а systemd таймер запускает полноценный сервис. Поэтому к задаче можно применять возможности systemd: зависимости, ограничения, переменные окружения, права пользователя, перезапуск, журналирование и проверку статуса.
Пример настройки systemd таймера
Разберем пример: нужно каждый день в 02:00 создавать резервную копию каталога /var/www/site. Для этого настроим systemd timer, который будет запускать скрипт резервного копирования по расписанию.
Сначала создайте скрипт:
sudo nano /usr/local/bin/backup-site.sh
Добавьте в файл команды:
#!/bin/bash
BACKUP_DIR="/backup"
SOURCE_DIR="/var/www/site"
DATE=$(date +%F)
mkdir -p "$BACKUP_DIR"
tar -czf "$BACKUP_DIR/site-$DATE.tar.gz" "$SOURCE_DIR"
find "$BACKUP_DIR" -type f -name "site-*.tar.gz" -mtime +14 -delete
Этот скрипт будет создавать архив каталога /var/www/site в папке /backup, добавлять дату в имя файла и удалять старые копии, которым больше 14 дней.
Сделайте его исполняемым:
sudo chmod +x /usr/local/bin/backup-site.sh
Теперь создайте service-файл. Он будет описывать, какую команду должен запускать systemd:
sudo nano /etc/systemd/system/backup-site.service
Добавьте в него:
[Unit]
Description=Backup site files
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-site.sh
Параметр Type=oneshot подходит для задач, которые запускаются, выполняют действие и завершаются. Резервное копирование как раз относится к таким задачам.
Далее создайте timer-файл:
sudo nano /etc/systemd/system/backup-site.timer
Добавьте в него расписание:
[Unit]
Description=Run site backup every day
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
Строка OnCalendar=*-*-* 02:00:00 означает, что задача будет запускаться каждый день в 02:00. А параметр Persistent=true нужен на случай, если сервер был выключен в момент запуска. После включения systemd выполнит пропущенную задачу.
Создав оба файла, перечитайте конфигурацию systemd:
sudo systemctl daemon-reload
Затем включите таймер и сразу запустите его:
sudo systemctl enable --now backup-site.timer
Проверьте, появился ли таймер в списке активных:
systemctl list-timers backup-site.timer
Чтобы не ждать запуска по расписанию, можно вручную выполнить service-файл:
sudo systemctl start backup-site.service
Проверьте статус выполнения командой:
sudo systemctl status backup-site.service
Если задача завершилась с ошибкой, посмотрите журнал:
journalctl -u backup-site.service
Чтобы вывести только последние записи, используйте команду:
journalctl -u backup-site.service -n 50
Теперь бэкап будет запускаться автоматически каждый день в 02:00. Результат выполнения можно проверить через systemctl и journalctl, поэтому отдельный лог-файл для базового сценария не обязателен.
Cron или systemd таймер: что выбрать
Cron лучше подходит для простых пользовательских задач, где нужно просто выполнить команду по расписанию. Например, раз в день запустить скрипт, очистить временную папку, сделать небольшой бэкап или отправить отчет. Его проще настроить: достаточно одной строки в crontab, без отдельных service- и timer-файлов.
Systemd таймеры удобнее, когда задача связана с обслуживанием системы или сервера. Они позволяют не только задать расписание, но и контролировать выполнение: смотреть статус, читать логи через журнал systemd, запускать задачу вручную как сервис и привязывать ее к другим условиям. Например, можно запускать задачу после появления сети или выполнить пропущенный запуск после перезагрузки.
Рассмотрим несколько конкретных задач:
| Задача | Что подойдет лучше |
|---|---|
| Простая команда по расписанию | cron |
| Личный скрипт пользователя | cron |
| Задача, для которой нужны статус и логи | systemd таймер |
| Резервное копирование на сервере | systemd таймер |
| Запуск после пропущенного времени при выключенной системе | systemd таймер |
| Быстрая настройка без дополнительных файлов | cron |
| Задача с зависимостью от сети или другого сервиса | systemd таймер |
Чек-лист перед запуском cron
Перед добавлением задачи в crontab стоит проверить несколько моментов:
- Убедитесь, что команда работает вручную из терминала. Сначала запустите ее сами и проверьте результат.
- Укажите полный путь к скрипту или программе. Например, лучше использовать
/usr/bin/php,/usr/bin/python3или/home/user/script.sh, а не только php, python3 или script.sh. - Проверьте права на запуск скрипта. Если это shell-скрипт, у файла должны быть права на выполнение.
- Убедитесь, что в начале скрипта указан интерпретатор, например
#!/bin/bash. - Проверьте, от имени какого пользователя будет выполняться задача. У него должны быть права на нужные файлы и каталоги.
- Укажите рабочие каталоги явно, если скрипт зависит от текущей папки.
- Задайте важные переменные окружения в crontab или внутри скрипта.
- Настройте запись вывода и ошибок в лог.
- Проверьте расписание.
- Убедитесь, что задача не запускается повторно, пока предыдущий запуск еще не завершился.
- Проверьте, хватает ли места на диске.
- Сначала протестируйте задачу на безопасном расписании. Например, запустите ее один раз через cron и проверьте лог, а уже потом ставьте постоянный запуск.
Добавив задачу, проверьте список crontab командой crontab -l и убедитесь, что запись сохранилась.
Чек-лист перед запуском systemd таймера
Ошибки в основных файлах таймера могут привести к тому, что задача не запустится по расписанию или завершится сразу после старта. Поэтому важно выполнить несколько действий:
- Запустите вручную скрипт или команду из ExecStart.
- Проверьте, что у скрипта есть право на выполнение.
- Укажите полный путь к скрипту или программе.
- Убедитесь, что файлы лежат в
/etc/systemd/system/, например backup-site.service и backup-site.timer. - Проверьте имена файлов. Таймер backup-site.timer по умолчанию запускает backup-site.service.
- Проверьте строку OnCalendar, чтобы задача запускалась в нужное время.
- Добавьте
Persistent=true, если пропущенный запуск нужно выполнить после включения системы. - После создания или изменения файлов выполните
sudo systemctl daemon-reload. - Запустите сервис вручную командой
sudo systemctl start backup-site.service. - Проверьте статус через sudo systemctl status backup-site.service.
- Если задача завершилась с ошибкой, посмотрите журнал:
journalctl -u backup-site.service -n 50. - Включите таймер командой
sudo systemctl enable --now backup-site.timer. - Проверьте таймер в списке активных:
systemctl list-timers backup-site.timer. - Убедитесь, что задачу запускает нужный пользователь. Если это не должен быть root, укажите
User=в service-файле.
Если задача связана с резервными копиями, обновлениями или системными службами, заранее проверьте права, пути к файлам и поведение скрипта при ошибке – в противном случае вы усложните себе администрирование VPS после сбоя.
Заключение
Мы рассмотрели два ключевых инструмента автоматизации на Linux‑сервере: классический cron и современный systemd таймер. У каждого из них свои сильные стороны.
Cron остается отличным выбором для простых повторяющихся задач: он прост в настройке, универсален и знаком большинству администраторов. Systemd таймеры выигрывает в сложных сценариях – когда нужно учитывать состояние служб, запускать задачи после определенных событий или управлять зависимостями.
Выбрав подходящий инструмент и грамотно настроив расписание, вы освободите время для более важных задач, а сервер будет работать стабильнее и надежнее. Используйте автоматизацию осознанно – и она станет вашим надежным помощником.
Перейти на оригинал