Cron, Anacron и At

Cron, anacron и at — инструменты Linux и Unix-подобных систем для запуска команд по расписанию.
Cron выполняет повторяющиеся задачи в заданное время, anacron запускает пропущенные периодические задачи после включения компьютера, а at предназначен для однократного отложенного запуска.

Руководство ориентировано на Linux. Конкретные пути, имена служб и доступные параметры могут отличаться в зависимости от дистрибутива и реализации cron.

Содержание

Выбор инструмента

Инструмент Назначение Что будет после выключения компьютера
cron Регулярный запуск в конкретное время Пропущенный запуск обычно не выполняется
anacron Регулярный запуск с периодом в днях Пропущенная задача запускается после включения
at Однократный запуск в указанное время Зависит от работы службы atd; просроченное задание обычно выполняется после запуска службы
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 cron

Fedora и RHEL

Обычно используется cronie:

sudo dnf install cronie
sudo systemctl enable --now crond

Проверка:

systemctl status crond

Arch 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.sh

PATH

Одна из самых частых проблем — команда работает в терминале, но не работает из 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.py

SHELL

По умолчанию часто используется /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.sh

MAILTO

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.sh

upload.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-backup

Anacron

anacron выполняет периодические задания, которые могли быть пропущены из-за выключения компьютера.

В отличие от cron, anacron обычно оперирует периодами в днях:

Anacron не предназначен для точного запуска, например каждый день ровно в 02:30. Он гарантирует, что задача будет выполнена после наступления периода, когда компьютер снова станет доступен.

Упрощённая логика:

Наступил срок задания?
        │
        ├── нет → ничего не делать
        │
        └── да
             │
             ├── компьютер выключен → запуск невозможен
             │
             └── компьютер включён → подождать задержку и запустить

Anacron хранит отметки о последних выполнениях, поэтому знает, какие задания просрочены.

Установка anacron

Ubuntu и Debian

sudo apt update
sudo apt install anacron

Fedora и 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 atd

Fedora и RHEL

sudo dnf install at
sudo systemctl enable --now atd

Arch 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

Задание появляется в очереди:

atq

batch не гарантирует точное время запуска. Он подходит для несрочных ресурсоёмких задач, но не заменяет полноценный менеджер очередей или систему управления ресурсами.

Права доступа

Cron

Доступ к crontab может регулироваться файлами:

/etc/cron.allow
/etc/cron.deny

Типичная логика:

  1. если существует cron.allow, пользоваться crontab могут только перечисленные в нём пользователи;
  2. если cron.allow отсутствует, проверяется cron.deny;
  3. точное поведение зависит от реализации и настроек системы.

Один пользователь указывается на каждой строке:

alice
backup
deploy

Проверить права файлов:

sudo ls -l /etc/cron.allow /etc/cron.deny

At

Для 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 cron

Fedora и 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/syslog

Fedora и 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=/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/logs

Cron не создаёт отсутствующие родительские каталоги.

Задание запускается дважды

Возможные причины:

Посмотреть пользовательский 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 не компенсирует пропущенные запуски. Используйте:

Не выполняется файл из /etc/cron.daily

Проверьте:

sudo run-parts --test /etc/cron.daily

Убедитесь, что файл:

Проверить тип файла:

file /etc/cron.daily/my-job

Удалить CRLF:

sed -i 's/\r$//' /etc/cron.daily/my-job

At не выполняет задания

Проверьте службу:

systemctl status atd

Запустите её:

sudo systemctl enable --now atd

Проверьте очередь:

atq

Проверьте журнал:

sudo journalctl -u atd

Безопасность

Задания планировщика выполняются с правами пользователя, которому принадлежит расписание. Системные задания от root имеют полный доступ к системе.

Основные рекомендации:

Права на системный скрипт:

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 выполняет однократное задание в будущем.