цены сверены 20 октября 2026 года

Задачи по расписанию на VPS: cron и таймеры systemd

Для простой задачи по расписанию хватит cron: команда crontab -e и одна строка. Таймеры systemd нужны, когда важны журнал, зависимости и запуск пропущенных задач после перезагрузки.

Задачи по расписанию на VPS: cron и таймеры systemd
Содержание
  1. Как поставить задачу в cron
  2. Что значат пять звёздочек
  3. Задача сработала, но где посмотреть результат
  4. В терминале работает, а в cron нет. Почему
  5. Как сделать то же самое таймером systemd
  6. Так что выбрать
  7. С чего начать
Команды проверены 12 октября 2026 годачистая Ubuntu 24.04 · cron, systemd 255Как мы проверяем

Скрипт резервной копии готов: вы запускаете его руками, он отрабатывает, архив появляется. Теперь хочется, чтобы он запускался сам каждую ночь в 03:00, а вы утром только проверяли, что всё прошло. На Ubuntu для этого есть два способа, cron и таймеры systemd. Разберём оба на этом же скрипте /home/user/backup.sh.

Как поставить задачу в cron

Cron это служба, которая запускает команды по расписанию. В Ubuntu 24.04 она уже установлена и работает, так что ставить ничего не нужно. Убедиться можно так:

systemctl status cron

В ответе ищите строку active (running): она значит, что служба запущена.

Задачи хранятся в личной таблице пользователя, она называется crontab. Открыть её и посмотреть содержимое:

crontab -e
crontab -l

crontab -e открывает таблицу в редакторе. При первом запуске система спросит, какой редактор взять, и nano вполне подойдёт. crontab -l просто выводит задачи, ничего не меняя. Таблица у каждого пользователя своя, поэтому задачи root и вашего обычного пользователя не смешиваются.

Что значат пять звёздочек

Строка crontab состоит из пяти полей времени и команды:

┌ минута (0-59)
│ ┌ час (0-23)
│ │ ┌ день месяца (1-31)
│ │ │ ┌ месяц (1-12)
│ │ │ │ ┌ день недели (0-7, 0 и 7 это воскресенье)
│ │ │ │ │
* * * * *  команда

Звёздочка значит «любое значение». Наша ночная копия выглядит так: 0 3 * * *, то есть нулевая минута третьего часа, любой день. Вот ещё несколько расписаний, которые встречаются чаще всего:

*/5 * * * *   /home/user/check.sh
0 3 * * *     /home/user/backup.sh
30 9 * * 1    /home/user/report.sh
0 0 1 * *     /home/user/monthly.sh
@reboot       /home/user/start.sh

Сверху вниз: каждые 5 минут, каждый день в 03:00, по понедельникам в 09:30, первого числа в полночь и один раз при запуске сервера. Значения можно перечислить через запятую (1,15) или задать диапазон через дефис: 1-5 в поле дня недели значит с понедельника по пятницу.

Одна ловушка: время считается по часовому поясу сервера, а он часто стоит UTC. Проверьте его командой timedatectl, иначе «03:00» наступит в 06:00 по Москве.

Задача сработала, но где посмотреть результат

Всё, что скрипт печатает, cron по умолчанию отправляет по локальной почте. Но на VPS почтовой программы обычно нет, и вывод просто пропадает. Так что дописывайте его в файл:

0 3 * * * /home/user/backup.sh >> /home/user/backup.log 2>&1

>> дописывает обычный вывод в backup.log, а 2>&1 отправляет туда же ошибки. Без этой второй части вы увидите, что копия прошла, но не увидите, почему она упала. Если вывод не нужен совсем, вместо файла поставьте /dev/null.

Сам факт запуска cron записывает в журнал systemd:

journalctl -u cron --since today

В строках CMD видно, когда, от какого пользователя и какая команда запустилась. Но сам вывод команды туда не попадает, поэтому файл из примера выше всё равно нужен. Подробнее о журналах: журналы и службы systemd.

В терминале работает, а в cron нет. Почему

Это самая частая жалоба, и причина почти всегда одна: cron запускает команды в урезанном окружении. Он не читает ваши .bashrc и .profile, а команды выполняет через /bin/sh, а не через bash. В Ubuntu 24.04 cron берёт PATH из /etc/environment, там есть системные каталоги вроде /usr/bin и /usr/local/bin. Зато всё, что вы добавляли в PATH сами, cron не видит: виртуальное окружение Python, ~/.local/bin, Node.js из nvm.

Поэтому в команде пишите полные пути: /usr/bin/python3 /home/user/bot/run.py, а не python3 run.py. Где лежит программа, подскажет which python3.

Другой путь: задать переменные в начале crontab, тогда они действуют на все строки ниже:

SHELL=/bin/bash
PATH=/home/user/.local/bin:/usr/local/bin:/usr/bin:/bin
MAILTO=""

SHELL выбирает оболочку, PATH перечисляет каталоги, где искать программы, а MAILTO="" отключает письма. Каталог ~/.local/bin здесь записан полностью, потому что знак ~ cron в этой строке не раскрывает.

Ещё три мелочи, на которых спотыкаются:

  • Текущий каталог у задачи не тот, что у вас в терминале. Пишите полные пути к файлам или начните команду с cd /home/user/bot &&.
  • Скрипту нужна первая строка #!/bin/bash и право на запуск: chmod +x /home/user/backup.sh.
  • Знак % cron считает концом команды. Строка date +%F > file.txt выполнится как date +, и файл не появится. Перед процентом ставьте обратную косую: date +\%F.

Если задача молчит, первым делом проверьте пути и знак %: в большинстве случаев дело в них.

Как сделать то же самое таймером systemd

Таймер systemd устроен как пара файлов. Служба (.service) описывает, что запускать, а таймер (.timer) описывает, когда. Переведём на таймер нашу ночную копию.

Сначала служба:

sudo nano /etc/systemd/system/backup.service
[Unit]
Description=Резервная копия

[Service]
Type=oneshot
ExecStart=/home/user/backup.sh
User=user

Type=oneshot говорит systemd, что задача выполнится и завершится, а не будет работать постоянно. ExecStart указывает полный путь к скрипту, User задаёт, от чьего имени его запускать.

Теперь таймер:

sudo nano /etc/systemd/system/backup.timer
[Unit]
Description=Ежедневный запуск резервной копии

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target

OnCalendar задаёт то же расписание: каждый день в 03:00. А Persistent=true делает то, чего cron не умеет: если сервер в 03:00 был выключен, копия запустится сразу после включения. Имена файлов совпадают, backup.service и backup.timer, и по этому совпадению systemd понимает, какую службу запускать.

Остаётся включить таймер:

sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers

daemon-reload заставляет systemd прочитать новые файлы. enable --now включает таймер и сохраняет его после перезагрузки. Сама копия при этом не запустится сейчас, она дождётся 03:00. list-timers покажет, когда таймер сработал последний раз и когда сработает в следующий.

Расписание удобно проверить заранее: systemd-analyze calendar "Mon *-*-* 09:30" печатает ближайший момент срабатывания. Запустить копию вручную, не дожидаясь ночи, можно командой sudo systemctl start backup.service, а её вывод лежит в journalctl -u backup.service, без всяких перенаправлений в файл.

Так что выбрать

Что важно Cron Таймер systemd
Настройка одна строка два файла
Вывод и ошибки в файл вручную сами в журнал
Сервер был выключен запуск теряется Persistent=true запустит после включения
Зависимости от других служб нет есть (After=, Requires=)
Окружение урезанное задаётся в файле службы

Если задача короткая и потерять один запуск не страшно, берите cron: почистить папку, проверить сайт, обновить данные. Если задача важная, должна оставлять журнал или зависит от сети и базы, берите таймер. Резервную копию можно делать любым способом, общая схема есть в статье резервные копии VPS. А если по расписанию запускается бот на Python, пригодится статья сервер для Telegram-бота.

С чего начать

Поставьте ночную копию одной строкой в cron, с выводом в backup.log, и утром загляните в этот файл. Если там пусто или ошибка, вернитесь к разделу про окружение: скорее всего, не хватает полного пути. Нужен сервер под такие задачи: на странице подбора VPS в базе 262 тарифов от 140 ₽ в месяц, цены сверены 20 октября 2026 года.