Learning Platform
Глоссарий Troubleshooting
Урок 17.04 · 18 мин
Начальный
anacronatschedulingone-shot tasks

Что такое anacron

cron хорошо работает на серверах с постоянным uptime. Но что если у тебя laptop, который ты выключаешь на ночь и в выходные? Cron job 0 3 * * * (каждый день в 03:00) пропустится: VM не работает в 03:00.

anacron решает эту проблему. Идея: вместо точного «в 03:00», anacron говорит «минимум раз в N дней». Он запоминает, когда последний раз задача выполнялась, и если прошло больше N — запустит при ближайшем boot.

На современных systemd-дистрибутивах эту функцию заменяет Persistent=true в systemd timer (см. урок 03). Но anacron всё ещё распространён на:

  • Ubuntu desktop (для apt-daily, apt-daily-upgrade в legacy-режиме);
  • RHEL/CentOS Server с traditional cron;
  • любые laptops/desktops, где systemd-timer-ы не настроили.

Для Junior DE: знать что это есть и зачем — must. Часто работать с этим напрямую не придётся.

Где живёт anacron

Установка: anacron обычно ставится автоматически с пакетом cron или отдельно (apt install anacron).

Конфиг: /etc/anacrontab.

$ cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HOME=/root
LOGNAME=root

# These replace cron's entries
1	5	cron.daily	run-parts --report /etc/cron.daily
7	10	cron.weekly	run-parts --report /etc/cron.weekly
@monthly 15	cron.monthly	run-parts --report /etc/cron.monthly

Формат строки anacron:

PERIOD  DELAY  JOB-IDENTIFIER  COMMAND
  • PERIOD — минимальный интервал в днях (1, 7, или @monthly).
  • DELAY — задержка в минутах после старта anacron (для разноса запусков по времени).
  • JOB-IDENTIFIER — уникальное имя задачи (анакрон использует его как ключ для timestamp файла).
  • COMMAND — что выполнить.

В примере выше:

  • 1 5 cron.daily ... — каждый день, с задержкой 5 минут после anacron-start, выполнить все скрипты из /etc/cron.daily/.
  • 7 10 cron.weekly ... — раз в 7 дней, с задержкой 10 минут.
  • @monthly 15 cron.monthly ... — раз в месяц, задержка 15 минут.

Как anacron работает под капотом

$ ls /var/spool/anacron/
cron.daily   cron.monthly   cron.weekly

$ cat /var/spool/anacron/cron.daily
20260513

В каждом файле — дата последнего успешного запуска (формат YYYYMMDD). При запуске anacron:

  1. Читает /etc/anacrontab.
  2. Для каждой job сравнивает текущую дату с timestamp в /var/spool/anacron/JOB-NAME.
  3. Если прошло больше PERIOD дней — добавляет в очередь на выполнение.
  4. После DELAY минут — запускает команды последовательно.
  5. После успеха обновляет timestamp.

Когда anacron запускается

На современных Ubuntu/Debian — через cron:

$ cat /etc/cron.d/anacron
30 7    * * *   root    [ -x /etc/init.d/anacron ] && update-rc.d anacron start ...

Или через systemd:

$ systemctl list-units --type=service | grep anacron
anacron.service       loaded active running Run anacron jobs

Идея: anacron запускается раз в день (или при boot), смотрит на свой to-do список, выполняет «пропущенные».

anacron vs cron: ключевая разница

anacron vs cron

Разные модели запуска для разных типов машин.

Aspect
cron
anacron
Минимальный интервал
1 минута
1 день
Если пропустили
Пропускаем, ждём следующего раза
Запустим при ближайшей возможности
Подход
Точное время (06:00)
Минимум раз в N дней
Где живёт
/var/spool/cron/crontabs/USER, /etc/cron.d/
/etc/anacrontab, /var/spool/anacron/
Кто запускает
cron daemon (всегда)
anacron запускает один раз и выходит
Для чего
Servers с 24/7 uptime
Laptops/desktops, intermittent uptime
Зрелое replacement
systemd timer с Persistent=true

Реальный кейс DE: laptop с локальным dev-окружением

Сценарий: у тебя на личном laptop крутится локальная Postgres, чистится /tmp, обновляется dev-данные. Хочешь, чтобы это работало даже если laptop был off ночью.

С cron 0 3 * * * /opt/cleanup.sh — не сработает: laptop спал.

С anacron в /etc/anacrontab:

1  5  dev-cleanup  /opt/cleanup.sh

Через 5 минут после старта anacron (при первом boot за день), если прошло >= 1 день с прошлого запуска — выполнит /opt/cleanup.sh.

С systemd timer (современный путь):

[Timer]
OnCalendar=daily
Persistent=true

То же поведение, но в современном synthax.

at: однократное запланированное задание

at — для разового запуска: «выполни эту команду завтра в 18:00». В отличие от cron/timer, не recurring.

# Установить, если нет:
$ sudo apt install at

# Запустить at-сервис (на современной Ubuntu):
$ sudo systemctl enable --now atd

atd — daemon, который держит очередь и запускает в положенное время.

Создать запланированную задачу

# Интерактивно: вводим команды, заканчиваем Ctrl+D
$ at 18:00 tomorrow
warning: commands will be executed using /bin/sh
at> echo "Hello from at" > /tmp/at-test.log
at> /opt/etl/one-time-fix.sh
at> <EOT>  # Ctrl+D
job 5 at Wed May 14 18:00:00 2026

# Через stdin:
$ echo "/opt/etl/cleanup.sh" | at 03:00 tomorrow

# Через here-doc:
$ at now + 30 minutes <<EOF
/opt/etl/run.sh
echo "done"
EOF

Форматы времени

at понимает много форматов:

at 18:00                    # сегодня в 18:00 (или завтра, если уже прошло)
at 18:00 tomorrow
at 18:00 2026-05-14
at noon                     # 12:00
at midnight                 # 00:00
at teatime                  # 16:00 (древняя british традиция)
at now + 1 hour
at now + 30 minutes
at now + 2 days
at 18:00 next mon           # следующий понедельник в 18:00

Просмотр очереди: atq

$ atq
5	Wed May 14 18:00:00 2026 a etl
6	Wed May 14 03:00:00 2026 a etl
7	Thu May 15 12:00:00 2026 a etl

# Что внутри задачи 5:
$ at -c 5
#!/bin/sh
# atrun uid=1001 gid=1001
# mail etl 0
...
echo "Hello from at" > /tmp/at-test.log
/opt/etl/one-time-fix.sh

Удалить задачу: atrm

$ atrm 5

Логи

at отправляет stdout/stderr задачи email на user-владельца (как cron). Поэтому почти всегда — redirect внутрь команды:

$ at 18:00 tomorrow <<EOF
/opt/etl/run.sh > /var/log/at-job-$(date +%s).log 2>&1
EOF

Сам atd логирует в journal:

$ journalctl -u atd --since today
May 13 12:34:56 prod-vm atd[2345]: Job 5 will be executed at Wed May 14 18:00:00 2026

DE-сценарий: запланировать data backfill на выходные

Реальная ситуация: в пятницу вечером ты обнаружил, что нужно перезапустить ETL для исторического периода. На production-VM не хочешь запускать сейчас (рабочие часы, нагрузка). Хочешь, чтобы запустилось в субботу в 03:00, когда нагрузка минимальная.

$ at 03:00 saturday <<'EOF'
cd /opt/etl
./backfill.sh --start 2026-01-01 --end 2026-04-30 >> /var/log/backfill.log 2>&1
EOF

Готово. Скрипт запустится один раз в указанное время.

Альтернативы:

  1. systemd timer с OnCalendar=Sat 03:00 — но это recurring (каждую субботу). Можно после первого запуска systemctl disable timer, но это hacky.
  2. OnCalendar=2026-05-16 03:00 (точная дата) — запустится только один раз. Persistent работает, но нужно потом удалять unit.
  3. at — самый чистый для one-off.

anacron vs at: разные задачи

anacron vs at: для разного

Не путать!

anacronrecurring, missing-tolerant
atодноразовая в будущем
cronrecurring, exact time
systemd timerrecurring + всё лучшее

Все четыре сосуществуют на современной системе. Выбор зависит от задачи:

  • One-off в будущем -> at.
  • Recurring + persistent + dependencies + structured logs -> systemd timer.
  • Recurring, простой однострочник, нет deps -> cron.
  • Recurring, intermittent uptime, нет systemd -> anacron.

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

at и cron имеют allow/deny списки. Если у тебя нет права использовать at:

$ at now + 1 minute <<<'echo hi'
You do not have permission to use at.

Проверь:

$ cat /etc/at.deny
guest
nobody

# Или (если есть):
$ cat /etc/at.allow
# Если этот файл существует, разрешено только перечисленным.

Аналогично для cron: /etc/cron.deny, /etc/cron.allow. На production иногда стоит ограничить — только определённые users могут планировать задачи.

Попробуй сам

  1. Что у тебя в anacrontab:
    cat /etc/anacrontab 2>/dev/null || echo "anacron не установлен"
  2. Когда последние запускались anacron jobs:
    ls -la /var/spool/anacron/ 2>/dev/null
  3. Установи at и попробуй (если ещё нет):
    sudo apt install at
    sudo systemctl enable --now atd
    echo "echo 'hello from at' > /tmp/at-test.log" | at now + 2 minutes
    atq
    # Через 2 минуты:
    cat /tmp/at-test.log
  4. Список запланированных at-задач:
    atq
  5. Удалить at-задачу:
    atrm <JOB-ID>

macOS-различия

  • На macOS at есть, но atd не запущен по умолчанию. Активация: sudo launchctl load -F /System/Library/LaunchDaemons/com.apple.atrun.plist. Sandbox-восстановления могут сломать.
  • anacron на macOS обычно не используется — есть periodic (свой launchd-based аналог) и pmset для wake-on-schedule.
  • Для one-off задач на macOS часто проще launchd job с StartCalendarInterval.

Главное

  • anacron — для машин с непостоянным uptime (laptops, desktops). Гарантирует «минимум раз в N дней». В /etc/anacrontab: PERIOD DELAY JOB-ID COMMAND.
  • На современных systemd-дистрибутивах Persistent=true в timer заменяет anacron.
  • at — для одноразовых запланированных задач. Не recurring.
  • at TIME запускает interactive prompt (Ctrl+D), либо через stdin.
  • Форматы времени: 18:00 tomorrow, now + 30 minutes, noon, next mon.
  • atq — очередь, atrm JOB-ID — удалить.
  • at шлёт stdout/stderr email (как cron) — redirect внутри команды.
  • Выбор инструмента:
    • one-off в будущем -> at;
    • recurring + production-grade -> systemd timer;
    • recurring simple -> cron;
    • recurring intermittent + нет systemd -> anacron.
  • Доступ: /etc/at.allow, /etc/at.deny, аналогично для cron.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. Для чего предназначен `anacron`?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 4