Многие знают, как пользоваться crontab. Это хороший и полезный инструмент. Но если в системе есть systemd, решения на его основе могут быть удобнее и гибче.

Создаем файл сервиса: /etc/systemd/system/mytask.service [Unit] Description=My Hourly PHP Script

[Service]

#Укажите путь к интерпретатору и вашему скрипту

ExecStart=/usr/bin/php /var/www/scripts/hourly_job.php

#Рекомендуется запускать от имени непривилегированного пользователя

User=www-data

#Тип oneshot подходит для задач, которые выполняются и завершаются

Type=oneshot

И файл таймера для него: /etc/systemd/system/mytask.timer [Unit] Description=Runs mytask.service every hour

[Timer]

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

Persistent=true

[Install] WantedBy=timers.target

Далее последовательно выполняем: systemctl daemon-reload systemctl enable --now mytask.timer

Полезные команды: systemctl list-timers # список активных таймеров journalctl -u mytask.service # логи конкретного скрипта systemctl start mytask.service # ручной запуск задачи «сейчас»

systemd даёт более гибкие условия запуска:

  • квантование не по минутам, а по секундам, а также привязка к событиям: через 5 минут после загрузки, через 10 минут после завершения предыдущего запуска или при изменении состояния системы;
  • Persistent=true заставит задачу выполниться, если она была пропущена (например, если выключить сервер, то при его включении все пропущенные таймеры активируются автоматически);
  • логирование работает «из коробки». В cron приходится вручную перенаправлять вывод команды в файл;
  • есть контроль дубликатов. Пока выполняется один запуск таймера, второй не начнётся. В cron же, если задача не успела выполниться за минуту, в следующую минуту она всё равно снова запустится.