#Скрипты с claude -p
Продвинутый уровень · Урок 4 из 7 · около 20 минут · Нужно: Запуск и сохранение динамического workflow · Сверено с Claude Code v2.1.285 (stable) 09.10.2026
#Цель
К концу урока вы сможете написать скрипт, который запускает Claude Code без человека за клавиатурой, читает его JSON-результат и код выхода и ограничивает его инструментами и числом ходов, нужными для задачи.
#Что понадобится
- Один из ваших репозиториев с командой запуска тестов и ваша копия шаблона для практики с Node.js LTS: проверка запускается из копии. Если хотите практиковаться в копии шаблона, используйте её в обеих ролях. Подготовьте в репозитории папку
.practice/, как описано в уроке 1 Начального уровня, если ещё не сделали этого. - bash и
jqв macOS, Linux или WSL 2. - Расход лимита: небольшой. Каждый запуск
claude -p— одна короткая сессия.
#Идея
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).
#Разбор примера
В своём репозитории:
- Задайте один вопрос и сохраните 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-результат. Итоговый проект Продвинутого уровня использует его повторно.
Критерии приёмки:
- Bash-скрипт
scripts/review-staged.sh, закоммиченный и исполняемый. - Он подаёт
git diff --cached— подготовленные изменения (git diff) — в один вызовclaude -p. Claude не нужен Bash, чтобы прочитать diff, потому что тот приходит на stdin (Add Claude to a build script). - В этом вызове промпт стоит сразу после
-p, как в примерах Pipe data through Claude и Add Claude to a build script, и передаются--output-format json,--permission-mode dontAsk,--allowedToolsтолько сRead,GrepиGlobи--max-turnsс числом от 1 до 10. В macOS, Linux и WSL инструментов Glob и Grep по умолчанию нет, и упоминание любого из них в--allowedToolsвозвращает оба (Glob tool behavior). - Он вызывает
claudeпо имени, а не по пути и не черезnpx, и не меняетPATH: так проверка подставляет вместо него заглушку. - Он сохраняет JSON по пути из первого аргумента или в
.practice/a-4-result.json, если аргумента нет, создавая папку при необходимости. - Он печатает текст
resultи завершается с ненулевым кодом, если так завершилсяclaudeили еслиis_errorравенtrue. - Если ничего не подготовлено, он сообщает об этом и завершается с ненулевым кодом, не вызывая Claude.
git diff --cached --quietзавершается с кодом 0, когда ничего не подготовлено (git diff).
Закоммитьте скрипт. Затем подготовьте небольшое изменение, например исправление в одну строку, и запустите scripts/review-staged.sh один раз: он сохранит .practice/a-4-result.json. Прочитайте ревью, прежде чем коммитить это изменение.
#Проверка
Урок пройден, когда выполнено всё это:
-
scripts/review-staged.shзакоммичен и исполняем. - В его вызове
claude -pпромпт стоит сразу после-p, запрашивается JSON, используется режимdontAsk, заранее одобрены толькоRead,GrepиGlob, а число ходов ограничено 10 или меньше. - Он подаёт на вход подготовленный diff, сохраняет JSON туда, куда указывает аргумент, печатает результат, завершается с ненулевым кодом при неудачном запуске и не вызывает Claude, когда ничего не подготовлено.
-
.practice/a-4-result.jsonсодержит запуск, успешно завершившийся в пределах вашего ограничения. - Самопроверка (не тестируется): на шаге 4 разбора примера вы видели, как запуск остановился на
--max-turns.
Запустите 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 $?; проверка запускает закоммиченный скрипт, поэтому коммитьте каждое исправление, прежде чем снова запускать проверку. Если не проходит четвёртый пункт, подготовьте изменение и запустите скрипт снова: запуск, остановленный вашим ограничением, не засчитывается, так что поднимите ограничение или сузьте промпт.
#Осторожно
- Запуск
-pне показывает диалог доверия: он выполняет хуки из.claude/settings.jsonпроекта и подключает серверы из его.mcp.jsonдаже в папке, которой вы никогда не доверяли (Start faster with bare mode). Прежде чем запускать Claude Code из скрипта в чужом репозитории, передайте--setting-sources user, чтобы Claude Code не читал ни файлы настроек проекта, ни его.mcp.json(What runs before you trust a folder). - Если задан
ANTHROPIC_API_KEY, запуск-pвсегда использует этот ключ вместо вашего плана (Authentication precedence). Полеtotal_cost_usdв JSON — оценка на стороне клиента, а не ваш счёт (Track cost and usage). - В папке, которой вы никогда не доверяли, запуск
-pигнорирует правилаpermissions.allowиз.claude/settings.jsonпроекта и печатает в stderr предупреждениеthis workspace has not been trusted; доверие к родительской папке не считается (Project allow rules and workspace trust, Error reference). Передавайте нужные скрипту правила в командной строке через--allowedTools.
#Что дальше
- Run Claude Code programmatically: структурированный вывод с
--json-schema, потоковый JSON и продолжение запуска через--resumeс егоsession_id. - Approve the plan before it runs: запуск workflow, сохранённого на прошлом уроке, из скрипта с
Workflow(<name>)в правилах allow. - Agent SDK overview: тот же цикл агента из Python или TypeScript.
Источники: 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 → · Тема: Автоматизация · Застряли на уроке?