Cron, Anacron и At
Cron, anacron и at — инструменты Linux и Unix-подобных систем для запуска команд по расписанию.
Cron выполняет повторяющиеся задачи в заданное время, anacron запускает пропущенные периодические задачи после включения компьютера, а at предназначен для однократного отложенного запуска.
Руководство ориентировано на Linux. Конкретные пути, имена служб и доступные параметры могут отличаться в зависимости от дистрибутива и реализации cron.
Содержание
- Выбор инструмента
- Cron
- Установка и запуск cron
- Пользовательский crontab
- Синтаксис cron
- Специальные расписания cron
- Переменные окружения в cron
- Системные задания cron
- Каталоги cron
- Практические примеры cron
- Предотвращение параллельных запусков
- Anacron
- Установка anacron
- Настройка anacron
- Практические примеры anacron
- At
- Установка at
- Создание заданий at
- Управление заданиями at
- Команда batch
- Права доступа
- Журналы и диагностика
- Типичные проблемы
- Безопасность
- Шпаргалка
Выбор инструмента
| Инструмент | Назначение | Что будет после выключения компьютера |
|---|---|---|
cron |
Регулярный запуск в конкретное время | Пропущенный запуск обычно не выполняется |
anacron |
Регулярный запуск с периодом в днях | Пропущенная задача запускается после включения |
at |
Однократный запуск в указанное время | Зависит от работы службы atd; просроченное задание обычно выполняется после запуска службы |
batch |
Однократный запуск при снижении нагрузки | Ждёт подходящего уровня нагрузки |
Примеры выбора:
- выполнять резервное копирование ежедневно в
02:00на постоянно работающем сервере —cron; - выполнять резервное копирование примерно раз в день на ноутбуке —
anacron; - выключить компьютер через два часа —
at; - запустить тяжёлую задачу, когда нагрузка снизится, —
batch.
Cron
cron — фоновая служба, которая регулярно проверяет расписание и запускает соответствующие команды.
Расписание называется crontab, сокращение от cron table. У каждого пользователя может быть собственный crontab. Кроме того, в системе существуют общие расписания и каталоги периодических заданий.
Типичные имена службы:
cron Debian, Ubuntu
crond Fedora, RHEL, Arch LinuxУстановка и запуск cron
Во многих системах cron уже установлен.
Ubuntu и Debian
sudo apt update
sudo apt install cron
sudo systemctl enable --now cronПроверка:
systemctl status cronFedora и RHEL
Обычно используется cronie:
sudo dnf install cronie
sudo systemctl enable --now crondПроверка:
systemctl status crondArch Linux
sudo pacman -S cronie
sudo systemctl enable --now cronieПроверить наличие команды:
command -v crontabПользовательский crontab
Открыть расписание текущего пользователя:
crontab -eПри первом запуске система может предложить выбрать текстовый редактор.
Показать текущее расписание:
crontab -lУдалить весь crontab текущего пользователя:
crontab -rУдаление без дополнительного вопроса опасно. В некоторых реализациях можно запросить подтверждение:
crontab -i -rПеред изменениями удобно сделать резервную копию:
crontab -l > ~/crontab.backupВосстановить расписание:
crontab ~/crontab.backupРедактирование расписания другого пользователя выполняет администратор:
sudo crontab -u alice -eПоказать его расписание:
sudo crontab -u alice -lНе редактируйте файлы пользовательских crontab вручную. Используйте команду crontab.
Синтаксис cron
Обычная строка пользовательского crontab состоит из пяти полей времени и команды:
минута час день-месяца месяц день-недели командаСхема:
┌──────── минута: 0–59
│ ┌────── час: 0–23
│ │ ┌──── день месяца: 1–31
│ │ │ ┌── месяц: 1–12
│ │ │ │ ┌ день недели: 0–7, где 0 и 7 — воскресенье
│ │ │ │ │
* * * * * командаПример:
30 2 * * * /home/alice/bin/backup.shКоманда запускается ежедневно в 02:30.
Допустимые конструкции
| Конструкция | Значение |
|---|---|
* |
Любое допустимое значение |
5 |
Конкретное значение |
1,5,10 |
Список значений |
1-5 |
Диапазон |
*/10 |
Каждые 10 единиц |
1-20/2 |
Каждое второе значение в диапазоне |
Примеры расписаний
Каждую минуту:
* * * * * /home/alice/bin/job.shКаждые пять минут:
*/5 * * * * /home/alice/bin/job.shКаждый час в нулевую минуту:
0 * * * * /home/alice/bin/job.shКаждый день в 03:15:
15 3 * * * /home/alice/bin/job.shПо понедельникам в 09:00:
0 9 * * 1 /home/alice/bin/job.shПо рабочим дням в 18:30:
30 18 * * 1-5 /home/alice/bin/job.shПо субботам и воскресеньям в полдень:
0 12 * * 6,0 /home/alice/bin/job.shПервого числа каждого месяца в 00:05:
5 0 1 * * /home/alice/bin/job.shВ январе и июле:
0 4 1 1,7 * /home/alice/bin/job.shКаждые 15 минут с 08:00 до 18:59:
*/15 8-18 * * * /home/alice/bin/job.shВ 09:00, 12:00 и 18:00:
0 9,12,18 * * * /home/alice/bin/job.shДень месяца и день недели
Если одновременно ограничены поля дня месяца и дня недели, во многих реализациях cron задача выполняется, когда совпадает хотя бы одно из них.
Например:
0 9 1 * 1 /home/alice/bin/job.shЭта запись обычно означает запуск:
- первого числа каждого месяца;
- каждый понедельник.
Это не обязательно означает «только когда первое число выпало на понедельник».
Для сложного условия проверяйте дату внутри команды:
0 9 1-7 * * [ "$(date +\%u)" -eq 1 ] && /home/alice/bin/job.shТакое задание запускается в первый понедельник месяца.
Секунды
Классический cron не имеет поля секунд. Минимальная стандартная точность расписания — одна минута.
Запись с шестью временными полями может поддерживаться отдельными реализациями или другими планировщиками, но не является переносимым форматом обычного crontab.
Специальные расписания cron
Вместо пяти полей времени можно использовать специальные строки:
| Строка | Приблизительный эквивалент |
|---|---|
@reboot |
При запуске службы cron или системы |
@yearly |
0 0 1 1 * |
@annually |
0 0 1 1 * |
@monthly |
0 0 1 * * |
@weekly |
0 0 * * 0 |
@daily |
0 0 * * * |
@midnight |
0 0 * * * |
@hourly |
0 * * * * |
Примеры:
@reboot /home/alice/bin/start-service.sh
@hourly /home/alice/bin/update-cache.sh
@daily /home/alice/bin/backup.sh@reboot означает запуск после старта cron, а не обязательно после каждого входа пользователя. Сеть, файловые системы и другие службы к этому моменту могут быть ещё не готовы.
Если заданию после загрузки требуется пауза:
@reboot sleep 60 && /home/alice/bin/start-service.shДля управления службами при запуске системы обычно надёжнее использовать systemd, а не @reboot.
Переменные окружения в cron
Cron запускает команды в ограниченном окружении. Интерактивные настройки оболочки, например .bashrc, обычно не загружаются.
В начале crontab можно задать переменные:
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
HOME=/home/alice
MAILTO=alice@example.com
0 2 * * * /home/alice/bin/backup.shPATH
Одна из самых частых проблем — команда работает в терминале, но не работает из cron.
Вместо:
0 2 * * * pg_dump app > /home/alice/backup.sqlлучше использовать полный путь:
0 2 * * * /usr/bin/pg_dump app > /home/alice/backup.sqlНайти путь к команде:
command -v pg_dumpЛибо явно определить PATH:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binРабочий каталог
Cron не обязан запускать команду из каталога проекта. Явно переходите в нужный каталог:
0 2 * * * cd /home/alice/projects/app && /usr/bin/python3 cleanup.pyЕщё надёжнее использовать абсолютные пути:
0 2 * * * /usr/bin/python3 /home/alice/projects/app/cleanup.pySHELL
По умолчанию часто используется /bin/sh:
SHELL=/bin/shЕсли команда требует возможностей Bash:
SHELL=/bin/bashЛибо запускайте Bash явно:
0 2 * * * /bin/bash /home/alice/bin/backup.shСкрипт может самостоятельно указывать интерпретатор:
#!/usr/bin/env bash
set -euo pipefailПосле этого он должен быть исполняемым:
chmod +x ~/bin/backup.shMAILTO
Cron может отправлять вывод задания локальной почтовой системой:
MAILTO=alice@example.comОтключение почтовых уведомлений:
MAILTO=""Для отправки писем должен быть настроен почтовый агент. На минимальных серверных установках его может не быть.
Символ %
В команде crontab неэкранированный символ % может иметь специальное значение: он завершает командную часть, а оставшийся текст передаётся команде через стандартный ввод.
Поэтому % в форматах date нужно экранировать:
0 2 * * * /home/alice/bin/backup.sh > "/home/alice/logs/backup-$(date +\%F).log" 2>&1Внутри отдельного shell-скрипта экранирование % для cron не требуется.
Системные задания cron
Основной системный файл:
/etc/crontabВ отличие от пользовательского crontab, системный формат содержит дополнительное поле пользователя:
минута час день-месяца месяц день-недели пользователь командаПример:
30 2 * * * root /usr/local/sbin/system-backupСхема:
┌──────── минута
│ ┌────── час
│ │ ┌──── день месяца
│ │ │ ┌── месяц
│ │ │ │ ┌ день недели
│ │ │ │ │ ┌ пользователь
│ │ │ │ │ │
* * * * * root командаВ каталоге:
/etc/cron.d/обычно используется такой же системный формат с полем пользователя.
Пример файла /etc/cron.d/myapp:
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
*/10 * * * * appuser /usr/local/bin/myapp-cleanupДля файлов в /etc/cron.d/ часто действуют ограничения на имена. Безопасный вариант — использовать только буквы, цифры, _ и -, без расширений вроде .bak.
После изменения crontab перезапуск cron обычно не требуется: служба перечитывает расписание автоматически.
Каталоги cron
В Linux часто используются каталоги:
/etc/cron.hourly/
/etc/cron.daily/
/etc/cron.weekly/
/etc/cron.monthly/Скрипт можно разместить, например, в:
/etc/cron.daily/my-backupОн должен быть исполняемым:
sudo chmod +x /etc/cron.daily/my-backupПример скрипта:
#!/usr/bin/env bash
set -euo pipefail
/usr/bin/tar -czf /var/backups/etc.tar.gz /etcФайлы из таких каталогов часто запускаются через run-parts. У run-parts могут быть строгие требования к именам файлов. Например, файл с точкой в имени может быть пропущен.
Проверить, какие файлы будут запущены:
run-parts --test /etc/cron.dailyЗапустить все подходящие файлы вручную:
sudo run-parts /etc/cron.dailyВ некоторых дистрибутивах эти каталоги запускает cron, а в других — anacron или systemd timers.
Практические примеры cron
Запись вывода в журнал
0 2 * * * /home/alice/bin/backup.sh >> /home/alice/logs/backup.log 2>&1Конструкция:
>> file добавить стандартный вывод в файл
2>&1 направить стандартный поток ошибок туда жеПерезапись журнала при каждом запуске:
0 2 * * * /home/alice/bin/backup.sh > /home/alice/logs/backup.log 2>&1Записывать только ошибки
0 2 * * * /home/alice/bin/backup.sh >/dev/null 2>>/home/alice/logs/backup-errors.logПолностью отключить вывод
0 2 * * * /home/alice/bin/backup.sh >/dev/null 2>&1Такой вариант усложняет диагностику. Лучше отключать вывод только после проверки задания.
Очистка старых файлов
Удалять архивы старше 30 дней:
15 4 * * * /usr/bin/find /home/alice/backups -type f -name '*.tar.gz' -mtime +30 -deleteСначала безопасно проверить результат без -delete:
find /home/alice/backups -type f -name '*.tar.gz' -mtime +30 -printРезервное копирование каталога
Файл ~/bin/backup-home.sh:
#!/usr/bin/env bash
set -euo pipefail
backup_dir="/home/alice/backups"
timestamp="$(date +%Y-%m-%d_%H-%M-%S)"
mkdir -p "$backup_dir"
tar -czf "$backup_dir/home-$timestamp.tar.gz" \
/home/alice/documentsПрава:
chmod +x ~/bin/backup-home.shРасписание:
0 2 * * * /home/alice/bin/backup-home.sh >> /home/alice/logs/backup.log 2>&1Запуск только при успешном завершении предыдущей команды
0 3 * * * /home/alice/bin/backup.sh && /home/alice/bin/upload.shupload.sh запустится только при коде завершения 0 у backup.sh.
Запуск второй команды независимо от результата
0 3 * * * /home/alice/bin/backup.sh ; /home/alice/bin/notify.shОграничение времени выполнения
Если доступна команда timeout:
0 3 * * * /usr/bin/timeout 30m /home/alice/bin/backup.shЧерез 30 минут процессу будет отправлен сигнал завершения.
Случайная задержка
Чтобы несколько машин не запускали задачу одновременно:
0 3 * * * sleep $((RANDOM \% 900)) && /home/alice/bin/update.shЭтот пример требует Bash и использует задержку до 899 секунд:
SHELL=/bin/bashДля переносимости случайную задержку лучше реализовать внутри отдельного скрипта.
Предотвращение параллельных запусков
Если предыдущее выполнение ещё не завершилось, cron всё равно может запустить новый экземпляр.
В Linux для блокировки удобно использовать flock:
*/5 * * * * /usr/bin/flock -n /tmp/my-job.lock /home/alice/bin/my-job.shПараметр -n означает немедленный выход, если блокировка уже занята.
С отдельным файловым дескриптором:
*/5 * * * * /usr/bin/flock -n 9 /home/alice/bin/my-job.sh 9>/run/user/1000/my-job.lockОжидание блокировки до 30 секунд:
*/5 * * * * /usr/bin/flock -w 30 /tmp/my-job.lock /home/alice/bin/my-job.shДля системных задач файл блокировки обычно размещают в /run/lock:
0 2 * * * root /usr/bin/flock -n /run/lock/system-backup.lock /usr/local/sbin/system-backupAnacron
anacron выполняет периодические задания, которые могли быть пропущены из-за выключения компьютера.
В отличие от cron, anacron обычно оперирует периодами в днях:
- ежедневно;
- раз в несколько дней;
- еженедельно;
- ежемесячно.
Anacron не предназначен для точного запуска, например каждый день ровно в 02:30. Он гарантирует, что задача будет выполнена после наступления периода, когда компьютер снова станет доступен.
Упрощённая логика:
Наступил срок задания?
│
├── нет → ничего не делать
│
└── да
│
├── компьютер выключен → запуск невозможен
│
└── компьютер включён → подождать задержку и запуститьAnacron хранит отметки о последних выполнениях, поэтому знает, какие задания просрочены.
Установка anacron
Ubuntu и Debian
sudo apt update
sudo apt install anacronFedora и RHEL
Anacron обычно входит в пакет cronie-anacron:
sudo dnf install cronie-anacronПроверка:
command -v anacronОсновная конфигурация обычно находится в:
/etc/anacrontabНастройка anacron
Формат строки:
период-в-днях задержка-в-минутах идентификатор командаПример:
1 5 backup-daily /usr/local/bin/backup-daily
7 10 backup-weekly /usr/local/bin/backup-weekly
30 15 cleanup-monthly /usr/local/bin/cleanup-monthlyПоля означают:
| Поле | Назначение |
|---|---|
| Период | Через сколько дней задание должно повторяться |
| Задержка | Сколько минут подождать перед запуском |
| Идентификатор | Уникальное имя задания без пробелов |
| Команда | Запускаемая команда |
Задание:
1 5 backup-daily /usr/local/bin/backup-dailyозначает: если задача не выполнялась сегодня, подождать пять минут и запустить её.
Типичный /etc/anacrontab
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
RANDOM_DELAY=15
START_HOURS_RANGE=3-22
1 5 cron.daily nice run-parts /etc/cron.daily
7 10 cron.weekly nice run-parts /etc/cron.weekly
@monthly 15 cron.monthly nice run-parts /etc/cron.monthlyПеременные и поддержка специальных периодов зависят от реализации.
RANDOM_DELAY добавляет случайную задержку, чтобы задачи на нескольких машинах не запускались одновременно.
START_HOURS_RANGE ограничивает часы, в которые anacron может начинать задания.
Метки последнего запуска
Anacron хранит временные метки в системном каталоге, например:
/var/spool/anacron/Имена файлов обычно соответствуют идентификаторам заданий.
Не изменяйте эти файлы без необходимости: удаление метки может привести к повторному запуску задачи.
Проверка конфигурации
Показать, какие задания anacron считает нужными для запуска, без выполнения:
sudo anacron -TВ некоторых реализациях -T только проверяет синтаксис. Доступные параметры следует уточнять через:
man anacronПринудительно выполнить задания независимо от меток:
sudo anacron -fЗапустить немедленно, игнорируя задержки:
sudo anacron -nОбъединение обоих режимов:
sudo anacron -fnЭта команда может запустить все настроенные задачи, поэтому применять её следует осторожно.
Подробный вывод:
sudo anacron -dПараметр -d запускает anacron в переднем плане и выводит сообщения в терминал.
Практические примеры anacron
Ежедневное резервное копирование ноутбука
Скрипт:
/home/alice/bin/daily-backup.shПример системной строки в /etc/anacrontab:
1 10 alice-daily-backup su - alice -c '/home/alice/bin/daily-backup.sh'Команда запускается не чаще одного раза в день с задержкой 10 минут.
При работе с пользовательскими задачами учитывайте, что системный anacron может запускаться от root. Явно указывайте нужного пользователя и проверяйте права создаваемых файлов.
Запуск каждые семь дней
7 15 weekly-report /usr/local/bin/create-weekly-reportЕсли компьютер не работал в назначенный день, задача будет выполнена после следующего запуска anacron.
Ежемесячная очистка
Если реализация поддерживает @monthly:
@monthly 20 monthly-cleanup /usr/local/bin/monthly-cleanupИначе можно использовать приблизительный период:
30 20 monthly-cleanup /usr/local/bin/monthly-cleanupПериод 30 означает каждые 30 дней и не совпадает точно с календарными месяцами.
Пользовательский anacron
Anacron можно запускать с отдельным файлом конфигурации и каталогом меток, если реализация поддерживает соответствующие параметры.
Пример пользовательского файла:
1 5 user-backup /home/alice/bin/backup.shЗапуск:
anacron -t /home/alice/.config/anacrontab \
-S /home/alice/.local/state/anacronНеобходимые параметры зависят от версии anacron. Проверьте их:
anacron --help
man anacronСам пользовательский anacron тоже нужно периодически запускать, например через cron или пользовательский systemd timer.
At
at планирует однократное выполнение команды в будущем.
Для работы используется служба:
atdПосле выполнения задание автоматически удаляется из очереди.
Установка at
Ubuntu и Debian
sudo apt update
sudo apt install at
sudo systemctl enable --now atdFedora и RHEL
sudo dnf install at
sudo systemctl enable --now atdArch Linux
sudo pacman -S at
sudo systemctl enable --now atdПроверка:
systemctl status atdСоздание заданий at
Интерактивный режим
Запустить команду сегодня в 23:00:
at 23:00После этого появляется приглашение:
at>Введите команды:
at> /home/alice/bin/backup.sh
at> <Ctrl+D>Ctrl+D завершает ввод и сохраняет задание.
Через стандартный ввод
echo '/home/alice/bin/backup.sh' | at 23:00Через два часа:
echo '/home/alice/bin/backup.sh' | at now + 2 hoursЧерез 30 минут:
echo '/home/alice/bin/job.sh' | at now + 30 minutesЗавтра в 09:00:
echo '/home/alice/bin/report.sh' | at 09:00 tomorrowВ полночь:
echo '/home/alice/bin/job.sh' | at midnightВ полдень:
echo '/home/alice/bin/job.sh' | at noonВ пятницу в 17:30:
echo '/home/alice/bin/job.sh' | at 17:30 FridayПоддерживаемые форматы даты зависят от реализации и локали. Для важных заданий проверьте время, которое показывает at после создания задания.
Абсолютная дата
Формат может выглядеть так:
echo '/home/alice/bin/job.sh' | at 10:00 12/31/2026Или:
echo '/home/alice/bin/job.sh' | at 10:00 Dec 31 2026Интерпретация числовых дат зависит от реализации и локали. Во избежание неоднозначности предпочтительнее использовать название месяца.
Выполнение нескольких команд
at 23:00 <<'EOF'
cd /home/alice/project
/usr/bin/git pull
/usr/bin/python3 cleanup.py
EOFЗапуск скрипта
at -f /home/alice/jobs/night-job.sh 23:00Параметр -f читает команды из файла.
Запись вывода
echo '/home/alice/bin/job.sh >> /home/alice/logs/job.log 2>&1' |
at now + 10 minutesБез перенаправления вывода atd может попытаться отправить результат через локальную почту.
Рабочий каталог
Задание обычно запоминает текущий рабочий каталог на момент вызова at. Тем не менее для надёжности лучше использовать абсолютные пути и явный cd:
echo 'cd /home/alice/project && /usr/bin/python3 task.py' |
at now + 1 hourПеременные окружения
at сохраняет значительную часть текущего окружения, но не следует полагаться на интерактивные настройки оболочки. Пароли, токены и другие секреты не рекомендуется передавать через переменные окружения задания.
Управление заданиями at
Показать очередь текущего пользователя:
atqАльтернативная команда:
at -lПример результата:
7 Thu Sep 10 23:00:00 2026 a aliceЗдесь 7 — номер задания.
Показать содержимое задания:
at -c 7Вывод содержит сохранённое окружение и команды. Он может быть большим.
Удалить задание:
atrm 7Альтернативный вариант:
at -r 7Удалить несколько заданий:
atrm 7 8 9Пользователь видит и удаляет только свои задания. Администратор может управлять заданиями других пользователей.
Команда batch
batch помещает однократную команду в очередь, но запускает её только после снижения системной нагрузки до допустимого уровня.
Интерактивный запуск:
batchЗатем:
at> /home/alice/bin/heavy-job.sh
at> <Ctrl+D>Через конвейер:
echo '/home/alice/bin/heavy-job.sh' | batchЗадание появляется в очереди:
atqbatch не гарантирует точное время запуска. Он подходит для несрочных ресурсоёмких задач, но не заменяет полноценный менеджер очередей или систему управления ресурсами.
Права доступа
Cron
Доступ к crontab может регулироваться файлами:
/etc/cron.allow
/etc/cron.denyТипичная логика:
- если существует
cron.allow, пользоватьсяcrontabмогут только перечисленные в нём пользователи; - если
cron.allowотсутствует, проверяетсяcron.deny; - точное поведение зависит от реализации и настроек системы.
Один пользователь указывается на каждой строке:
alice
backup
deployПроверить права файлов:
sudo ls -l /etc/cron.allow /etc/cron.denyAt
Для at используются:
/etc/at.allow
/etc/at.denyПринцип аналогичен cron.allow и cron.deny.
Разрешить at только пользователю alice:
printf '%s\n' alice | sudo tee /etc/at.allow
sudo chmod 600 /etc/at.allow
sudo chown root:root /etc/at.allowНе изменяйте эти файлы, не проверив правила конкретного дистрибутива.
Журналы и диагностика
Проверка службы cron
Ubuntu и Debian:
systemctl status cron
journalctl -u cronFedora и RHEL:
systemctl status crond
journalctl -u crondСообщения в реальном времени:
sudo journalctl -fu cronИли:
sudo journalctl -fu crondПоиск записей cron в системном журнале
Ubuntu и Debian могут записывать события в /var/log/syslog:
sudo grep CRON /var/log/syslogFedora и RHEL могут использовать:
/var/log/cronПросмотр:
sudo tail -f /var/log/cronНаличие файлов зависит от настройки rsyslog и systemd-journald.
Проверка службы at
systemctl status atd
journalctl -u atdВ реальном времени:
sudo journalctl -fu atdПроверка задания вручную
Запускайте команду от того же пользователя и в похожем окружении:
sudo -u alice env -i \
HOME=/home/alice \
PATH=/usr/bin:/bin \
SHELL=/bin/sh \
/home/alice/bin/job.shЭто помогает обнаружить зависимость от переменных интерактивной оболочки.
Запись окружения cron
Временное диагностическое задание:
* * * * * /usr/bin/env > /tmp/cron-environment.txtПосле проверки удалите его из crontab.
Проверка факта запуска
* * * * * /usr/bin/date >> /tmp/cron-test.log 2>&1Подождите одну-две минуты и проверьте:
cat /tmp/cron-test.logПосле теста удалите задание.
Типичные проблемы
Команда работает вручную, но не из cron
Наиболее частые причины:
- ограниченный
PATH; - другой рабочий каталог;
- отсутствуют переменные окружения;
- не загружается
.bashrc; - скрипт не является исполняемым;
- используются относительные пути;
- у пользователя cron нет нужных прав;
- команда требует интерактивного терминала;
- неэкранированный
%изменил строку команды.
Надёжный вариант:
PATH=/usr/local/bin:/usr/bin:/bin
SHELL=/bin/bash
0 2 * * * cd /home/alice/project && /usr/bin/python3 /home/alice/project/task.py >> /home/alice/logs/task.log 2>&1Скрипт не запускается
Проверьте первую строку:
#!/usr/bin/env bashПрава:
chmod +x /home/alice/bin/job.shЗапуск вручную:
/home/alice/bin/job.sh
echo "$?"Проверка синтаксиса Bash:
bash -n /home/alice/bin/job.shНет журнала ошибок
Явно перенаправьте оба потока:
0 2 * * * /home/alice/bin/job.sh >> /home/alice/logs/job.log 2>&1Убедитесь, что каталог существует:
mkdir -p /home/alice/logsCron не создаёт отсутствующие родительские каталоги.
Задание запускается дважды
Возможные причины:
- одинаковая запись присутствует в нескольких crontab;
- скрипт установлен и в
/etc/cron.daily, и в пользовательском crontab; - одновременно используются cron и systemd timer;
- предыдущий запуск не успевает завершиться;
- день месяца и день недели заданы одновременно.
Посмотреть пользовательский crontab:
crontab -lПосмотреть системные расписания:
sudo cat /etc/crontab
sudo ls -la /etc/cron.dДля защиты от пересечения запусков используйте flock.
@reboot запускается слишком рано
Сеть или нужная служба может быть ещё недоступна.
Простой, но ограниченный вариант:
@reboot sleep 60 && /home/alice/bin/job.shДля задания с зависимостями от сети и других служб лучше создать systemd unit с корректными After= и Wants=.
Задание не выполнилось во время выключения
Обычный cron не компенсирует пропущенные запуски. Используйте:
anacronдля периодических задач;- systemd timer с
Persistent=true; - отдельную проверку последнего успешного выполнения внутри скрипта.
Не выполняется файл из /etc/cron.daily
Проверьте:
sudo run-parts --test /etc/cron.dailyУбедитесь, что файл:
- имеет допустимое имя;
- является исполняемым;
- содержит корректный shebang;
- не имеет Windows-переносов строк CRLF.
Проверить тип файла:
file /etc/cron.daily/my-jobУдалить CRLF:
sed -i 's/\r$//' /etc/cron.daily/my-jobAt не выполняет задания
Проверьте службу:
systemctl status atdЗапустите её:
sudo systemctl enable --now atdПроверьте очередь:
atqПроверьте журнал:
sudo journalctl -u atdБезопасность
Задания планировщика выполняются с правами пользователя, которому принадлежит расписание. Системные задания от root имеют полный доступ к системе.
Основные рекомендации:
- используйте абсолютные пути;
- ограничивайте права на скрипты и конфигурацию;
- не размещайте скрипты root в каталогах, доступных для записи обычным пользователям;
- не храните пароли и токены непосредственно в crontab;
- записывайте ошибки в защищённый журнал;
- используйте
flockдля задач, которые не должны пересекаться; - проверяйте команды вручную до добавления в расписание;
- ограничивайте доступ через
cron.allowиat.allow, если это необходимо; - не используйте ввод из ненадёжных источников без проверки;
- применяйте отдельного системного пользователя для сервисных задач;
- регулярно проверяйте пользовательские и системные расписания.
Права на системный скрипт:
sudo chown root:root /usr/local/sbin/system-backup
sudo chmod 750 /usr/local/sbin/system-backupПрава на пользовательский скрипт:
chmod 700 /home/alice/bin/backup.shСекреты лучше хранить в отдельном файле с ограниченными правами:
chmod 600 /home/alice/.config/myapp/credentialsПри этом сам скрипт не должен выводить секреты в журнал.
Шпаргалка
Cron
| Действие | Команда |
|---|---|
| Редактировать crontab | crontab -e |
| Показать crontab | crontab -l |
| Удалить crontab | crontab -r |
| Сохранить резервную копию | crontab -l > crontab.backup |
| Восстановить | crontab crontab.backup |
| Редактировать для пользователя | sudo crontab -u USER -e |
| Проверить службу Debian/Ubuntu | systemctl status cron |
| Проверить службу Fedora/RHEL | systemctl status crond |
Примеры cron
| Расписание | Запись |
|---|---|
| Каждую минуту | * * * * * command |
| Каждые 5 минут | */5 * * * * command |
| Каждый час | 0 * * * * command |
Ежедневно в 02:30 |
30 2 * * * command |
По понедельникам в 09:00 |
0 9 * * 1 command |
По рабочим дням в 18:00 |
0 18 * * 1-5 command |
| Первого числа месяца | 0 0 1 * * command |
| После запуска cron | @reboot command |
| Ежедневно | @daily command |
| Еженедельно | @weekly command |
Anacron
| Действие | Команда или запись |
|---|---|
| Конфигурация | /etc/anacrontab |
| Ежедневное задание с задержкой 5 минут | 1 5 job-id command |
| Еженедельное задание | 7 10 job-id command |
| Принудительно проверить задания | sudo anacron -f |
| Игнорировать задержки | sudo anacron -n |
| Запустить в переднем плане | sudo anacron -d |
| Принудительно и без задержек | sudo anacron -fn |
At
| Действие | Команда |
|---|---|
Запустить в 23:00 |
echo 'command' | at 23:00 |
| Запустить через два часа | echo 'command' | at now + 2 hours |
Запустить завтра в 09:00 |
echo 'command' | at 09:00 tomorrow |
| Читать команды из файла | at -f job.sh 23:00 |
| Показать очередь | atq |
| Показать задание | at -c JOB_ID |
| Удалить задание | atrm JOB_ID |
| Запустить при низкой нагрузке | echo 'command' | batch |
Минимум для запоминания
crontab -e редактировать регулярное расписание
crontab -l показать расписание
0 2 * * * /path/to/backup.sh запускать ежедневно в 02:00
*/5 * * * * /path/to/job.sh запускать каждые 5 минут
@reboot /path/to/start.sh запускать после старта cron
1 5 daily-job /path/to/job.sh anacron: не реже раза в день
7 10 weekly-job /path/to/job.sh anacron: не реже раза в неделю
echo '/path/to/job.sh' | at 23:00
echo '/path/to/job.sh' | at now + 2 hours
atq
atrm JOB_IDГлавное различие: cron привязывает запуск к календарному времени, anacron — к прошедшему периоду и компенсирует простой компьютера, а at выполняет однократное задание в будущем.