> Полный список статей есть в [llms.txt](https://docs.f3cloud.com/llms.txt). Markdown-версия есть у каждой страницы, достаточно добавить .md к её адресу. Эта страница в Markdown: [https://docs.f3cloud.com/ru/linux/cron-linux.md](https://docs.f3cloud.com/ru/linux/cron-linux.md).

# Cron в Linux – как запускать задачи по расписанию

Cron в Linux. Как запускать скрипты и команды по расписанию, как устроена строка crontab и что значат пять звёздочек, готовые примеры расписаний, где смотреть, выполнилась ли задача, и почему скрипт работает вручную, но не работает из cron. Проверено на Debian 12.

Резервную копию удобно делать каждую ночь, старые логи чистить раз в неделю, а проверку сайта запускать каждые пять минут. Выполнять такие команды вручную никто не будет, поэтому в Linux для этого есть **cron**, планировщик, который сам запускает команды в заданное время. В этой статье разберём, как устроен cron, как читать и писать строку расписания, добавим задачи, проверим, что они выполняются, и разберём ловушки, из-за которых задача молча не срабатывает. Все примеры мы проверили на тестовом сервере с Debian 12.

***

## Как работает cron

Cron это служба, которая постоянно работает на сервере и раз в минуту просматривает списки задач. Каждая задача состоит из расписания и команды. Если текущее время подходит под расписание, cron запускает команду и снова засыпает до следующей минуты. Поэтому самая частая периодичность, которую можно задать в cron, это раз в минуту, и задачи запускаются в начале минуты, в нулевую секунду. На тестовом сервере задача с расписанием «каждую минуту» выполнялась ровно в 12:08:01, 12:09:01 и так далее.

Списки задач называются **crontab**, и у каждого пользователя он свой. Задачи из crontab пользователя root выполняются с правами root, а задачи обычного пользователя с его правами. Редактируют crontab не напрямую, а командой `crontab -e`. Она открывает копию в текстовом редакторе, а после сохранения проверяет синтаксис и сообщает cron о новом расписании.

Главное, что нужно понимать о cron, касается окружения, в котором он запускает команды. Когда вы работаете в терминале, оболочка загружает ваши настройки, переменную `PATH` с длинным списком папок, где искать программы, и текущую папку, из которой вы вызвали команду. Cron ничего этого не делает. Мы записали окружение задачи в файл на тестовом сервере, и в нём оказалось всего несколько переменных. `PATH` содержал только `/usr/bin:/bin`, оболочкой был простой `/bin/sh`, а рабочей папкой домашняя папка пользователя. Отсюда и происходит большинство жалоб в духе «скрипт руками работает, а из cron нет». Программа из `/usr/local/bin` не находится, относительный путь к файлу указывает не туда, а синтаксис, понятный bash, не работает в `sh`.

Последнее, о чём стоит помнить, это время. Cron выполняет задачи по часам и часовому поясу самого сервера. На наших серверах с Debian 12 установлен пояс **Europe/Berlin**, поэтому задача, назначенная на 03:00, выполнится в 04:00 по московскому времени. Проверить часовой пояс сервера можно командой `timedatectl`.

***

## Как читать строку расписания

Каждая строка crontab состоит из пяти полей времени и команды.

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

Звёздочка означает «любое значение». Кроме чисел можно использовать перечисление через запятую `1,15`, диапазон через дефис `1-5` и шаг через косую черту `*/10`. Вот готовые примеры.

```text
* * * * *       каждую минуту
*/5 * * * *     каждые 5 минут
0 * * * *       в начале каждого часа
0 3 * * *       каждый день в 03:00
30 2 * * 1      по понедельникам в 02:30
0 9 * * 1-5     по будням в 09:00
0 0 1 * *       первого числа каждого месяца в полночь
@reboot         один раз после загрузки сервера
```

***

## 1. Откройте crontab

```bash
crontab -e
```

При первом запуске Debian спросит, в каком редакторе открывать файл. Нажмите <kbd>1</kbd> и <kbd>Enter</kbd>, чтобы выбрать самый простой, **nano**. Сменить выбор позже можно командой `select-editor`.

<figure><img src="https://docs.f3cloud.com/img/cron-select-editor.png" alt="Первый запуск crontab -e с выбором редактора, первым предложен nano"><figcaption><p>Выбор редактора при первом запуске</p></figcaption></figure>

Откроется файл с подсказками. Все строки, которые начинаются с `#`, это комментарии, cron их пропускает.

<figure><img src="https://docs.f3cloud.com/img/cron-crontab-nano.png" alt="Пустой crontab в редакторе nano со строками комментариев и подсказкой по формату"><figcaption><p>Новые задачи добавляются в конец файла</p></figcaption></figure>

***

## 2. Добавьте задачу

Перейдите в конец файла и допишите строку задачи. Для примера будем каждую ночь в 03:00 запускать скрипт резервного копирования и сохранять всё, что он выводит, в лог.

```text
0 3 * * * /opt/backup.sh >> /var/log/backup.log 2>&1
```

Обратите внимание на три вещи.

* **Полный путь к скрипту.** Пишите `/opt/backup.sh`, а не `backup.sh`, ведь cron запускает команду из домашней папки.
* **Перенаправление вывода.** `>> /var/log/backup.log 2>&1` дописывает в файл и обычный вывод, и ошибки. Без этого вы не узнаете, почему задача не сработала.
* **Пустая строка в конце.** Последняя строка файла должна заканчиваться переводом строки, поэтому после задачи нажмите <kbd>Enter</kbd>.

Сохраните файл сочетанием <kbd>Ctrl</kbd> + <kbd>O</kbd>, затем <kbd>Enter</kbd>, и выйдите сочетанием <kbd>Ctrl</kbd> + <kbd>X</kbd>. Если в строке нет ошибок, cron сообщит **crontab: installing new crontab**.

***

## 3. Проверьте, что задача выполняется

Посмотреть свои задачи можно командой `crontab -l`, а каждый запуск cron записывает в системный журнал.

```bash
# Список задач
crontab -l

# Последние запуски задач
journalctl -u cron -n 20 | grep CMD
```

<figure><img src="https://docs.f3cloud.com/img/cron-list-log.png" alt="Вывод crontab -l и строки лога, в которые задача каждую минуту записывала дату"><figcaption><p>Задачи на месте, тестовая задача пишет дату в лог каждую минуту</p></figcaption></figure>

Если задачу нужно проверить сразу, временно поставьте ей расписание `* * * * *`, дождитесь начала следующей минуты, посмотрите результат и верните нужное расписание.

***

## Полезные команды

```bash
crontab -e            # редактировать свои задачи
crontab -l            # показать свои задачи
crontab -r            # удалить все свои задачи без подтверждения
crontab -u ivan -l    # задачи другого пользователя, только для root
timedatectl           # часовой пояс сервера
```

> **crontab -r удаляет всё.**
>
> Буквы `r` и `e` стоят на клавиатуре рядом. `crontab -r` без вопросов стирает весь список задач, поэтому перед большими изменениями сохраните его копию командой `crontab -l > ~/crontab.bak`.

***

## Частые вопросы

<details>

<summary>Скрипт вручную работает, а из cron нет</summary>

1. Укажите полные пути ко всем программам и файлам. Путь к программе показывает `which`, например `which docker`.
2. Если скрипт использует возможности bash, первой строкой в нём должно быть `#!/bin/bash`, а у файла право на выполнение, `chmod +x`.
3. Перенаправьте вывод в лог, как в примере выше, и посмотрите, какую ошибку пишет скрипт.
4. Если нужны переменные окружения, задайте их в начале crontab, например `PATH=/usr/local/bin:/usr/bin:/bin`.

</details>

<details>

<summary>Команда с символом % не работает</summary>

Для cron знак `%` означает перевод строки, и всё, что стоит после него, команда получает на вход, а не в параметрах. Мы проверили это на задаче `date +%H:%M > файл`. Cron выполнил только `date +`, а файл так и не появился. Знак нужно экранировать обратной косой чертой, `date +\%H:\%M`.

<figure><img src="https://docs.f3cloud.com/img/cron-percent.png" alt="Журнал cron, где команда с неэкранированным знаком процента обрезана до date +"><figcaption><p>В последней строке команда обрезана на первом знаке %</p></figcaption></figure>

</details>

<details>

<summary>new crontab file is missing newline before EOF, can't install</summary>

Последняя строка файла не заканчивается переводом строки. Ответьте `y` на вопрос о повторном редактировании, перейдите в конец последней задачи, нажмите <kbd>Enter</kbd> и сохраните файл ещё раз.

</details>

<details>

<summary>Задача срабатывает не в то время</summary>

Cron работает по часовому поясу сервера. Проверьте его командой `timedatectl` и либо пересчитайте время задачи, либо смените пояс сервера, например `timedatectl set-timezone Europe/Moscow`. После смены пояса перезапустите cron командой `systemctl restart cron`.

</details>

<details>

<summary>Чем cron отличается от службы systemd</summary>

Cron запускает короткие задачи по расписанию, а служба systemd держит программу запущенной постоянно и перезапускает её после падения. Бота или веб-приложение правильнее оформить как [службу systemd](https://docs.f3cloud.com/ru/linux/systemd-services.md), а резервное копирование и очистку оставить cron.

</details>

***

## Наши ресурсы

**Telegram-канал:** [https://t.me/f3cloud_news](https://t.me/f3cloud_news)\
**Официальный сайт:** [https://f3cloud.com](https://f3cloud.com/ru)
