Мастер Claude · Блок 4. Skills и автоматизация

Урок 39 из 93 · ~10 мин чтения

Автоматизация через cron и launchd

Урок пока закрыт

Курс проходится последовательно.

К текущему уроку

Обновление, август 2026

Расписание больше не требует включённого компьютера: облачные routines выполняются на стороне Anthropic и запускаются по расписанию, по HTTP-вызову или по событию.

Актуальная версия: Урок 78. Routines

Почему это важно именно вам

Есть задачи, которые вы выполняете каждый день в одно и то же время. Открываете папку «Входящие», просматриваете новые файлы, понимаете, что появилось за ночь и что требует внимания сегодня. Или каждое утро в 9:00 заходите в Claude и копируете туда вчерашние документы, чтобы получить краткую сводку перед планёркой. Это не сложно, но это время — и это внимание, которое тратится до начала настоящей работы.

Прежде чем писать plist, знайте про три встроенных механизма: /loop <интервал> <промпт> внутри сессии, задачи рабочего стола для локального расписания без сессии и /schedule для облака. Cron и launchd нужны там, где задача завязана на ваши локальные скрипты и окружение.

Cron и launchd — это планировщики задач. Они умеют запускать любую команду по расписанию: каждый день в 9:00, каждый понедельник, каждый час. Если в эту команду встроить claude -p, то Claude будет автоматически обрабатывать ваши документы, формировать дайджесты, отправлять результаты в нужное место — и всё это без вашего участия. Вы просто приходите на работу и находите готовый результат.

Практический сценарий: каждое утро в 9:00 скрипт смотрит в папку «Входящие», собирает список файлов, добавленных за последние 24 часа, передаёт их Claude и получает краткую сводку — что пришло, от кого, что требует реакции. Сводка сохраняется в файл или приходит в Telegram. Это реально работает, занимает полчаса на настройку один раз и экономит десять минут каждое утро навсегда. Именно это мы и настроим в этом уроке.

Что это такое

Cron — это стандартный планировщик для Linux и macOS. Он читает файл расписания (crontab), и когда время совпадает с записью — запускает команду. Синтаксис записи выглядит загадочно (0 9 * * *), но за ним стоит простая идея: пять полей — минута, час, день месяца, месяц, день недели. Звёздочка означает «каждый».

Launchd — это родной планировщик macOS. Apple рекомендует его вместо cron для персональных задач на Mac. Он работает через XML-файлы с расширением .plist, которые кладутся в папку ~/Library/LaunchAgents/. Launchd умеет запускать задачу по расписанию, при входе в систему, при изменении файла — и автоматически перезапускать если что-то пошло не так.

Хорошая аналогия для обоих инструментов — это секретарь, которому вы однажды дали инструкцию: «каждое утро в 9:00 зайди в комнату с входящими документами, посмотри, что появилось, и положи мне на стол краткое резюме». Секретарь не задаёт вопросов, не забывает, не болеет. Просто делает — каждый день.

Разница между cron и launchd в контексте нашей задачи невелика: cron проще настроить двумя командами, launchd надёжнее на macOS (Apple постепенно ограничивает cron в новых версиях системы) и умеет автоматически перезапускаться если задача упала. Для критичных ежедневных задач лучше launchd. Для простых экспериментов — cron быстрее.

Ключевая идея

Автоматизация через расписание — это не про то, чтобы запустить claude и уйти. Это про то, чтобы Claude стал частью вашего рабочего процесса: пока вы едете в офис или пьёте кофе, он уже обработал ночные документы и подготовил вам контекст для дня.

Есть один важный технический нюанс, который ломает половину попыток настроить автоматизацию с Claude: переменные окружения. Когда вы работаете в терминале, ваш профиль ~/.zshenv или ~/.zshrc загружается автоматически, и в нём есть все токены и пути. Когда cron или launchd запускают задачу, они этого не делают: скрипт стартует в «чистой» среде, где нет ни PATH к программам, ни ваших переменных. Решение — явно загружать профиль в начале скрипта командой source ~/.zshenv и вызывать claude по полному пути.

Отдельно про доступ: если вы работаете по подписке, никакого ANTHROPIC_API_KEY у вас нет и быть не должно — вход сохранён локально, и фоновая задача им пользуется так же, как вы в терминале. Переменная с ключом нужна только тем, кто платит через Console по факту использования.

Как работает на практике

Разберём конкретный сценарий: ежедневный дайджест папки «Входящие» в 9:00.

Шаг 1. Создаём папку для скриптов

mkdir -p ~/scripts

Можно использовать любую папку. Главное — не класть скрипты с автоматизацией прямо на рабочий стол.

Шаг 2. Пишем скрипт

Создайте файл ~/scripts/morning-digest.sh со следующим содержимым:

#!/bin/bash

# Загружаем переменные окружения — без этого claude не найдёт токен
source ~/.zshenv

# Папка для мониторинга — поменяйте на свой путь
INBOX_DIR="$HOME/Documents/Входящие"

# Папка для результатов
OUTPUT_DIR="$HOME/Documents/Дайджесты"
mkdir -p "$OUTPUT_DIR"

# Файл с сегодняшним дайджестом
TODAY=$(date +%Y-%m-%d)
OUTPUT_FILE="$OUTPUT_DIR/digest-$TODAY.md"

# Собираем список файлов, добавленных за последние 24 часа
NEW_FILES=$(find "$INBOX_DIR" -maxdepth 1 -type f -mtime -1 2>/dev/null)

if [ -z "$NEW_FILES" ]; then
    echo "# Дайджест $TODAY" > "$OUTPUT_FILE"
    echo "" >> "$OUTPUT_FILE"
    echo "Новых файлов во входящих не найдено." >> "$OUTPUT_FILE"
    exit 0
fi

# Формируем промпт для Claude
PROMPT="Сделай краткий дайджест входящих документов за последние 24 часа.

Список новых файлов:
$NEW_FILES

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

В конце — раздел «Требует реакции сегодня» с файлами, которые судя по названию нельзя отложить.

Формат — Markdown, без лишних украшений."

# Запускаем Claude и сохраняем результат
echo "# Дайджест входящих — $TODAY" > "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
echo "$PROMPT" | claude -p >> "$OUTPUT_FILE" 2>/dev/null

echo "Дайджест сохранён: $OUTPUT_FILE"

Сохраните файл. Теперь дайте ему права на выполнение:

chmod +x ~/scripts/morning-digest.sh

Шаг 3. Проверяем, что скрипт работает вручную

Прежде чем настраивать расписание — запустите скрипт руками:

~/scripts/morning-digest.sh

Смотрите на результат. Если всё нормально — появится файл в папке ~/Documents/Дайджесты/. Если ошибка — скрипт сообщит о ней, и вы исправите до того, как настроите автозапуск.

Проверяйте скрипт вручную перед настройкой расписания

Самая частая причина, почему автоматизация «не работает» — скрипт падает в фоне, никто не видит ошибки, и кажется что launchd не запускает. Сначала запустите руками, убедитесь что работает, потом ставьте расписание.

Шаг 4. Настраиваем launchd

Создайте файл ~/Library/LaunchAgents/com.mywork.morning-digest.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.mywork.morning-digest</string>

    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>/Users/ВАШЕ_ИМЯ/scripts/morning-digest.sh</string>
    </array>

    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>9</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>

    <key>StandardOutPath</key>
    <string>/tmp/morning-digest.log</string>

    <key>StandardErrorPath</key>
    <string>/tmp/morning-digest-error.log</string>
</dict>
</plist>

Важно: замените ВАШЕ_ИМЯ на реальное имя вашего пользователя macOS. Узнать его можно командой whoami.

Почему не тильда в plist

В XML-файлах launchd нельзя использовать ~ как сокращение домашней папки. Нужен полный путь: /Users/pavelp/scripts/morning-digest.sh. Это одна из причин, почему скрипт не запускается, хотя в plist всё выглядит правильно.

Шаг 5. Регистрируем задачу

launchctl load ~/Library/LaunchAgents/com.mywork.morning-digest.plist

Эта команда регистрирует задачу. Теперь launchd знает о ней и запустит в 9:00.

Шаг 6. Проверяем, что задача зарегистрирована

launchctl list | grep morning-digest

Если задача появилась в списке — всё готово. Первое число в строке — код последнего завершения (0 = успех, другое = ошибка). Второй столбец — PID если сейчас выполняется.

Шаг 7. Проверяем прямо сейчас, не ждя 9:00

launchctl start com.mywork.morning-digest

Задача запустится немедленно. Проверьте, появился ли файл дайджеста:

ls ~/Documents/Дайджесты/

Если что-то пошло не так — смотрите логи:

cat /tmp/morning-digest-error.log

Девяносто процентов проблем видны прямо там.

Альтернатива: cron вместо launchd

Если хотите попроще — cron настраивается двумя командами. Откройте редактор расписания:

crontab -e

Добавьте строку:

0 9 * * * /bin/bash /Users/ВАШЕ_ИМЯ/scripts/morning-digest.sh >> /tmp/morning-digest.log 2>&1

Сохраните и выйдите. Cron сразу подхватит расписание. Проверить:

crontab -l

Разница от launchd: cron не запустится если компьютер был выключен в 9:00 — задача просто пропустится. Launchd можно настроить так, чтобы запустил пропущенную задачу при следующем включении (через ключ RunAtLoad).

Частые ошибки

Ошибка 1. Забыли source ~/.zshenv — claude не находится

Это самая частая проблема. В терминале claude -p работает, в скрипте по расписанию — нет. Ошибка в логах выглядит как Error: ANTHROPIC_API_KEY not set или command not found: claude.

Причина: cron и launchd запускают скрипт без загрузки вашего профиля — в нём нет ни PATH к claude, ни ваших переменных. На подписке ключа нет вовсе, и ошибка обычно выглядит как command not found: claude: лечится полным путём к программе и source ~/.zshenv. Сообщение ANTHROPIC_API_KEY not set появляется только у тех, кто работает через Console по ключу.

Исправление: первая строка после #!/bin/bash должна быть source ~/.zshenv. Если не помогает — проверьте, что ключ действительно прописан в ~/.zshenv, а не в ~/.zshrc (cron не загружает и его).

Ошибка 2. Тильда в plist вместо полного пути

Файл plist — это XML. В XML нет понятия «домашняя папка пользователя», поэтому ~/scripts/morning-digest.sh будет понят буквально как папка с именем тильда. Задача не запустится, ошибка будет неочевидной.

Исправление: всегда пишите полный путь в plist: /Users/yourname/scripts/morning-digest.sh. Имя пользователя — результат команды whoami.

Ошибка 3. Скрипт не имеет прав на выполнение

Создали файл скрипта, но забыли сделать его исполняемым. Launchd попробует запустить — получит «Permission denied» — молча упадёт.

Исправление: chmod +x ~/scripts/morning-digest.sh. Проверить права: ls -la ~/scripts/morning-digest.sh — должен быть флаг x в выводе.

Ошибка 4. Ждёте результата, но логи не смотрите

Задача зарегистрирована, время наступило, файл дайджеста не появился — и непонятно почему. Без логов вы будете гадать.

Исправление: всегда настраивайте StandardErrorPath в plist (или >> /tmp/script.log 2>&1 в cron). После первого запуска смотрите эти файлы — там написано всё, что нужно знать. Большинство проблем решаются за одну прочитанную строку ошибки.

Не размещайте .plist файлы на Яндекс.Диске

Папка ~/Library/LaunchAgents/ должна быть локальной. Если вы храните рабочие файлы на Яндекс.Диске (как многие), не кладите туда plist с секретами или токенами. Яндекс.Диск синхронизирует файлы в облако — ваши ключи окажутся там. plist файлы и скрипты с токенами — только локально.

Когда нужно / когда нет

Используйте расписание, когда:

Не используйте расписание, когда:

Хороший тест

Спросите себя: если бы у меня был ассистент, я бы попросил его делать это автоматически каждое утро? Если ответ «да» — расписание нужно. Если «нет, каждый раз нужно уточнять» — лучше запускать руками или через hook по событию.

Связь с другими уроками

День 9 — флаг --bg и фоновые задачи. Там разбирается как запускать Claude в фоне без ожидания ответа. Это полезно если ваш скрипт должен запустить несколько тяжёлых задач параллельно: вместо последовательного запуска через -p можно использовать --bg для каждой и не ждать завершения предыдущей.

День 34 — библиотека skills для директора. Скрипт для расписания отлично работает в связке со skills: вместо того, чтобы писать промпт прямо в скрипт, можно вызвать claude /дайджест-дня с нужными аргументами. Так промпт живёт в одном месте (в файле skill), а скрипт только передаёт данные.

День 41-42 — hooks и события. Расписание — это про время. Hooks — это про события: когда появился новый файл, когда закончилась сессия, когда выполнилась команда. Если вам нужно реагировать не по часам, а по факту — следующие уроки про это.

Задание на сегодня

Создайте скрипт ~/scripts/morning-digest.sh из примера выше, замените путь к папке на реальный (это может быть ~/Downloads, ~/Desktop или любая папка, куда к вам приходят документы). Запустите его вручную командой ~/scripts/morning-digest.sh и убедитесь, что появился файл с дайджестом в папке ~/Documents/Дайджесты/.

Критерий «выполнено»: скрипт запустился без ошибок и создал файл дайджеста. Настройку расписания через launchd можно сделать следующим шагом — но сначала убедитесь, что скрипт работает руками.

Резюме

Следующий урок откроется после отметки.