Прямой ответ
Регулярные задачи разработчика — чистка кэшей, бэкап dotfiles, обновление зависимостей, прогрев зеркала — живут в системном планировщике: на Linux это cron (проще) или systemd-таймеры (надёжнее), на macOS — launchd (с cron-совместимостью), на Windows — Планировщик задач (или cron внутри WSL2). Специфика именно ноутбука одна, но критичная: машина спит и выключается, поэтому «пропущенные» запуски — норма; планируйте задачи с учётом этого (systemd-таймеры умеют догонять пропущенное, cron — нет) и не размещайте на ноутбуке задачи, обязательные к точному времени — им место на сервере.
Cron: пять минут до рабочей схемы
# m h dom mon dow команда
0 9 * * 1-5 $HOME/bin/backup-dotfiles.sh >> $HOME/.local/state/backup.log 2>&1
30 3 * * 0 $HOME/bin/clean-caches.sh --older-than 30d >> $HOME/.local/state/clean.log 2>&1
Редактирование — только через crontab -e (прямая правка файлов ломает подхват). Правила, без которых cron молча не работает: абсолютные пути везде (PATH крона урезан — /usr/bin:/bin), перенаправление вывода в файл обязательно (иначе ошибки уходят в никуда или, хуже, почтовым спулом), % в команде экранируется. Скрипты для крона пишутся по принципам из статьи про автоматизацию рутины: set -euo pipefail, идемпотентность, понятный лог.
Systemd-таймеры: почему они лучше на современном Linux
Таймер — пара юнитов: backup.service (что делать) и backup.timer (когда). Преимущества перед cron, которые ощутимы именно на ноутбуке:
- Persistent=true — пропущенный во сне/выключении запуск выполняется при включении;
- OnBootSec/OnUnitActiveSec — относительные расписания («через 10 минут после загрузки», «раз в сутки после прошлого запуска») — для нерегулярно включаемой машины адекватнее абсолютного времени;
- каждое исполнение — под надзором systemd: лимиты памяти/CPU, таймауты, журнал в
journalctl -u backup.serviceбез самописных логов; systemctl list-timers— наглядный список с временами следующих запусков.
Цена — многословность (два файла вместо строки). Практика: одноразовые и учебные задачи — cron, долгоживущие и важные — таймеры.
Windows: Планировщик задач и WSL
Нативный путь — schtasks или GUI Планировщика: триггеры «по расписанию», «при входе», «при простое»; полезная для ноутбука настройка — «выполнять только при питании от сети» (тяжёлая задача на батарее — плохая идея) и «выполнять пропущенную задачу при первой возможности». Внутри WSL2 живёт обычный cron, но с оговоркой: WSL-дистрибутив активен, только пока открыт терминал или запущен Docker Desktop/служба WSL — для гарантированного крона внутри WSL включают автозапуск дистрибутива (systemd в WSL включается в /etc/wsl.conf). Подробности среды — в статье про WSL2. Альтернатива без админ-прав и планировщика — пользовательский скрипт-«страж», запускаемый из автозагрузки.
Типовые задачи разработчика на расписании
Полезный стартовый набор: ежедневный бэкап dotfiles и ключей (push в приватный репозиторий или зашифрованный архив — из статьи про dotfiles); еженедельная чистка кэшей сборки и старых Docker-образов; еженедельный uv lock --upgrade/npm update в отдельной ветке — зависимости обновляются малыми порциями, а не катастрофой раз в год; ежемесячная проверка восстанавливаемости бэкапа (тестовое восстановление в /tmp). Задачи, которые на ноутбуке держать нельзя: прод-деплои по расписанию, мониторинг с алертами, всё, что обязано выполниться вовремя — ноутбук не сервер.
Диагностика: задача «не сработала»
Порядок проверки: (1) планировщик жив — systemctl status cron / crontab -l / вкладка журнала Планировщика Windows; (2) лог исполнения — ваш файл или journalctl: чаще всего задача запускалась, но упала на PATH или переменных окружения; (3) время — ноутбук спал (cron пропуск не догоняет); (4) права — GUI-планировщики требуют явного указания учётки и «выполнять вне зависимости от регистрации». Классическая ошибка на стороне Windows: скрипт для PowerShell в задаче без -ExecutionPolicy Bypass -File — молча не исполняется.
Переносимость задач между машинами
Задачи планировщика — часть окружения, и хранить их стоит как код. Для cron это значит: содержимое кронтаба — файлом в dotfiles (crontab backup.cron при развёртывании), для systemd-таймеров — юниты в репозитории с командой установки в bootstrap-скрипте, для Windows — экспорт XML-задачи (schtasks /query /xml) в тот же репозиторий. Такой подход даёт два бонуса: переезд на новый ноутбук восстанавливает расписания вместе с dotfiles (процедура из статьи про перенос окружения), а список задач всегда на виду — через год вы увидите мёртвые задачи, которые молча не работают или, хуже, молча работают впустую.
Вторая переносимая практика — логирование задач в единый каталог (~/.local/state/<задача>.log) с ротацией по размеру: когда через месяц нужно понять, почему бэкап не приходил, ответ ищется в одном предсказуемом месте, а не в пяти разных. Для критичных задач добавьте проверку «свежести»: отдельный еженедельный скрипт смотрит дату последней успешной строки в логах и предупреждает, если задача молчит — молчаливый отказ планировщика опаснее громкого падения.
FAQ
Что выбрать на macOS: cron или launchd? Для простых пользовательских задач cron работает и достаточен; launchd (LaunchAgents) корректнее переживает сон и дает логирование. Apple исторически рекомендует launchd, но крон из macOS не удален.
Как не получить две задачи одновременно?
Обёртка flock -n /tmp/task.lock command (Linux) гарантирует один экземпляр: вторая копия при наложении выходов завершится сразу. Для долгих задач это обязательная страховка.
Подходит ли cron для запуска каждые несколько секунд? Нет, минимальный шаг — минута; чаще — это уже демон (systemd-сервис с Restart, постоянно живущий процесс) или планировщик приложения, а не системный cron.
Будут ли задачи работать от батареи? Технически да, но настройте планировщик на питание от сети для тяжёлых операций: чистка кэшей на 20% заряда — способ остаться без ноутбука в неподходящий момент.
Куда писать вывод задачи, чтобы не потерять и не забить диск?
В один файл на задачу внутри ~/.local/state/ с обрезкой по размеру (логрот или самописная проверка в начале скрипта). Отдельный каталог упрощает диагностику и бэкап, а ограничение размера спасает от сценария «задача спамит ошибкой, пока диск не кончился».
Стоит ли уведомлять об ошибках задач? Для критичных — да: строка в мессенджер или письмо при ненулевом коде возврата. Но уведомлять нужно о факте падения, а не о каждом запуске — иначе алерты начнут игнорировать через неделю.
Источники: man crontab, документация systemd.timer, Microsoft Task Scheduler (ссылки в шапке).