✻ Claude Code по-русски
🎧 Аудиокурс
🎧 Озвучка этой страницы готовится.

#Скрипты с claude -p

Продвинутый уровень · Урок 4 из 7 · около 20 минут · Нужно: Запуск и сохранение динамического workflow · Сверено с Claude Code v2.1.285 (stable) 09.10.2026

#Цель

К концу урока вы сможете написать скрипт, который запускает Claude Code без человека за клавиатурой, читает его JSON-результат и код выхода и ограничивает его инструментами и числом ходов, нужными для задачи.

#Что понадобится

#Идея

claude -p "<prompt>" выполняет один промпт без интерактивного интерфейса, печатает ответ и завершается с кодом 0 или ненулевым кодом, если запуск не удался (Run Claude Code programmatically). Он читает stdin, так что скрипт может подать на вход diff.

С --output-format json он печатает один JSON-объект с полями result, is_error, num_turns, session_id и permission_denials (SDKResultMessage). result содержит ответ или сообщение об ошибке, если что-то сломалось внутри запуска (Basic usage). subtype равен success или указывает, почему запуск остановился раньше времени, например error_max_turns; у такого запуска нет result (Handle the result). Проверяйте код выхода и is_error, прежде чем использовать result.

Ответить на запрос разрешения некому, поэтому всегда передавайте режим: запуск, где режим ничем не задан, может стартовать в режиме auto (Auto-approve tools). Ограничения задают три флага: --permission-mode dontAsk отклоняет каждый вызов, который иначе потребовал бы подтверждения, --allowedTools перечисляет то, что всё же можно запускать, а --max-turns ограничивает число ходов (CLI flags).

#Разбор примера

В своём репозитории:

  1. Задайте один вопрос и сохраните JSON:
claude -p "In one sentence, what does this repository do?" --output-format json --permission-mode dontAsk > .practice/a-4-first.json
echo "exit $?"
jq '{is_error, subtype, num_turns, session_id}' .practice/a-4-first.json
jq -r .result .practice/a-4-first.json

Будет выведено exit 0, затем "is_error": false и "subtype": "success" с числом ходов и ID сессии, затем одно предложение о вашем репозитории (формулировки у вас будут другими). Чтение файлов в рабочей папке не требует одобрения, поэтому dontAsk позволил Claude прочитать всё нужное (dontAsk mode). 2. Попросите то, что требует одобрения. --setting-sources user не пускает в запуск файлы настроек проекта (CLI flags), так что ни правило allow, ни режим auto-allow песочницы из урока 4 Среднего уровня не одобряют команду тестов (Auto-allow mode). При этом выпадают и правила deny проекта, например ваши правила для .env из того урока, поэтому в шагах 2–4 они передаются снова через --disallowedTools, который принимает правила deny (CLI flags):

claude -p "Run the test suite and say how many tests pass" --output-format json --permission-mode dontAsk --setting-sources user --disallowedTools "Read(./.env)" "Read(./.env.*)" > .practice/a-4-denied.json
jq -c '.permission_denials[] | {tool_name, command: .tool_input.command}' .practice/a-4-denied.json
jq -r .result .practice/a-4-denied.json

Каждая строка — вызов, отклонённый dontAsk (SDKPermissionDenial), например {"tool_name":"Bash","command":"npm test 2>&1 | tail -20"}; команду выбирает Claude, так что у вас она может отличаться. Результат сообщает, что Claude не смог запустить тесты (формулировки у вас будут другими). 3. Разрешите команду, которую показал шаг 2 (здесь npm test), и ограничьте число ходов:

claude -p "Run the test suite and say how many tests pass" --output-format json --permission-mode dontAsk --setting-sources user --disallowedTools "Read(./.env)" "Read(./.env.*)" --allowedTools "Bash(npm test *)" --max-turns 3 | jq '{subtype, num_turns, denied: (.permission_denials | length)}'

Будет показано "subtype": "success" и "denied": 0: на этот раз Claude запустил тесты. Пробел перед * важен, а завершающий * совпадает и с командой без аргументов (Wildcard patterns). Правило покрывает и конвейер вроде npm test 2>&1 | tail -20: Claude Code проверяет каждую часть конвейера отдельно, а tail — одна из команд только для чтения, которые выполняются без одобрения (Compound commands, Read-only commands). 4. Упритесь в ограничение. Эта задача требует двух шагов подряд, а --max-turns 1 разрешает один ход с вызовом инструментов. Оставьте Read и то же правило для Bash, что на шаге 3:

claude -p "Read the file that defines this project's test command, then run that command, then summarize any failures" --output-format json --permission-mode dontAsk --setting-sources user --disallowedTools "Read(./.env)" "Read(./.env.*)" --allowedTools "Read,Bash(npm test *)" --max-turns 1 > .practice/a-4-capped.json
echo "exit $?"
jq '{subtype, has_result: has("result")}' .practice/a-4-capped.json

Будет выведен ненулевой код выхода, затем "subtype": "error_max_turns" и "has_result": false: у запуска, остановленного ограничением, нет result. --max-turns считает только ходы с вызовом инструментов (Turns and messages), поэтому если запуск завершился, дайте задачу с большим числом шагов.

#Ваша очередь

Напишите ревью, которое можно запускать перед каждым коммитом: scripts/review-staged.sh отправляет подготовленные (staged) изменения Claude, печатает ревью и сохраняет JSON-результат. Итоговый проект Продвинутого уровня использует его повторно.

Критерии приёмки:

Закоммитьте скрипт. Затем подготовьте небольшое изменение, например исправление в одну строку, и запустите scripts/review-staged.sh один раз: он сохранит .practice/a-4-result.json. Прочитайте ревью, прежде чем коммитить это изменение.

#Проверка

Урок пройден, когда выполнено всё это:

Запустите npm run check -- a-4 --dir <your repo> из своей копии для практики или npm run check -- a-4 в самой копии. Проверка запускает ваш закоммиченный скрипт с заглушкой вместо claude, так что ваш лимит не расходуется.

Если не проходит первый пункт, выполните chmod +x scripts/review-staged.sh, затем git add и закоммитьте снова. Если не проходит второй пункт, прочитайте его подсказку: она называет флаг, который не нашёлся, или сообщает, что скрипт вызывает claude по пути или через npx либо меняет PATH. Сравните свою строку claude -p с критериями из задания, начиная с того, где стоит промпт. Если не проходит третий пункт, запустите скрипт вручную без подготовленных изменений и с подготовленным изменением и после каждого запуска выполните echo $?; проверка запускает закоммиченный скрипт, поэтому коммитьте каждое исправление, прежде чем снова запускать проверку. Если не проходит четвёртый пункт, подготовьте изменение и запустите скрипт снова: запуск, остановленный вашим ограничением, не засчитывается, так что поднимите ограничение или сузьте промпт.

#Осторожно

#Что дальше


Источники: Run Claude Code programmatically · CLI reference · Choose a permission mode · Configure permissions · Configure the sandboxed Bash tool · How the agent loop works · Agent SDK reference - TypeScript · Track cost and usage · Authentication · Tools reference · Error reference · git diff

← Запуск и сохранение динамического workflow · Оглавление Продвинутого уровня · GitHub Actions → · Тема: Автоматизация · Застряли на уроке?