Script Automation
You have a Claude Code workflow that works every time: pipe in the git diff, ask for a changelog entry, format it, append to CHANGELOG.md. You run it before every release. But it takes five manual steps and you forget the exact prompt every time. Scripting turns this from a manual workflow into a single command.
What You Will Walk Away With
Section titled “What You Will Walk Away With”- Print mode patterns for scripting Claude Code into pipelines
- Pre-commit hooks that run Claude Code before every commit
- Cron jobs for scheduled codebase maintenance
- Error handling and retry patterns for production scripts
Print Mode Fundamentals
Section titled “Print Mode Fundamentals”The -p flag makes Claude Code scriptable. It takes a prompt, processes it, prints the result, and exits:
# Basic usageclaude -p "What does this project do?"
# With piped inputcat error.log | claude -p "What caused this error?"
# With output formatclaude -p "List all TODO comments in the codebase" --output-format json
# With budget limitsclaude -p "Refactor src/utils.ts" --max-turns 5 --max-budget-usd 1.00Output Formats
Section titled “Output Formats”| Format | Use Case | Example |
|---|---|---|
text (default) | Human-readable output | --output-format text |
json | Script consumption | --output-format json |
stream-json | Real-time streaming | --output-format stream-json |
Pre-Commit Hooks
Section titled “Pre-Commit Hooks”Run Claude Code as a pre-commit check. This catches issues before code reaches the repository:
Basic Pre-Commit Review
Section titled “Basic Pre-Commit Review”#!/bin/bash# Quick review of staged changes
STAGED_DIFF=$(git diff --cached --no-color)
if [ -z "$STAGED_DIFF" ]; then exit 0fi
RESULT=$(echo "$STAGED_DIFF" | claude -p "Review this diff for critical issues only: \ security vulnerabilities, obvious bugs, and broken error handling. \ If you find CRITICAL issues, output 'BLOCK: [reason]'. \ If the code looks safe, output 'PASS'." \ --max-turns 3 --output-format text 2>&1)
if echo "$RESULT" | grep -q "BLOCK:"; then echo "Pre-commit review found issues:" echo "$RESULT" exit 1fi
exit 0Cron Jobs
Section titled “Cron Jobs”Daily Code Health Check
Section titled “Daily Code Health Check”#!/bin/bash# cron-health-check.sh -- Run daily at 6 AM# Crontab: 0 6 * * * /path/to/cron-health-check.sh
cd /path/to/project
REPORT=$(claude -p "Run a health check on this project: \ 1. Check for TypeScript errors: npx tsc --noEmit \ 2. Run the linter: npm run lint \ 3. Check for outdated dependencies: npm outdated \ 4. Summarize findings in a brief report" \ --max-turns 10 \ --dangerously-skip-permissions \ --output-format text 2>&1)
# Send via notification (adjust for your team's channel)echo "$REPORT" | mail -s "Daily Code Health: $(date +%Y-%m-%d)" team@company.comWeekly Dependency Audit
Section titled “Weekly Dependency Audit”#!/bin/bashcd /path/to/project
claude -p "Run npm audit and analyze the results. \ For each vulnerability: \ 1. Assess if it affects us (check if the vulnerable code path is used) \ 2. Check if an upgrade is available \ 3. Note any breaking changes in the upgrade \ Output a prioritized action list." \ --max-turns 8 \ --dangerously-skip-permissions \ --output-format text > /tmp/audit-report.txt
# Only notify if there are actionable findingsif grep -q "CRITICAL\|HIGH" /tmp/audit-report.txt; then cat /tmp/audit-report.txt # Send to your notification systemfiError Handling and Retry Patterns
Section titled “Error Handling and Retry Patterns”Robust Script Template
Section titled “Robust Script Template”#!/bin/bashset -euo pipefail
MAX_RETRIES=3RETRY_DELAY=5
run_claude() { local prompt="$1" local retries=0
while [ $retries -lt $MAX_RETRIES ]; do result=$(claude -p "$prompt" --max-turns 5 --output-format text 2>&1) exit_code=$?
if [ $exit_code -eq 0 ]; then echo "$result" return 0 fi
retries=$((retries + 1)) echo "Attempt $retries failed. Retrying in ${RETRY_DELAY}s..." >&2 sleep $RETRY_DELAY done
echo "Failed after $MAX_RETRIES attempts" >&2 return 1}
# Usagerun_claude "Analyze the test coverage report and identify untested code paths"When This Breaks
Section titled “When This Breaks”Script hangs waiting for permissions: In print mode, Claude Code stops when it needs permission for a dangerous operation. Use --dangerously-skip-permissions for trusted environments, or --allowedTools to pre-approve specific operations.
Output format inconsistency: Claude Code’s text output may vary between runs. When parsing output programmatically, use --output-format json and parse with jq. Do not rely on specific text formatting.
Budget exceeded mid-task: The --max-budget-usd flag stops execution when the budget is reached. For critical tasks, set a generous budget and monitor costs via /cost or OpenTelemetry.
Cron job environment differs from shell: Cron jobs run with a minimal environment. Ensure your PATH includes node and claude, and that all required environment variables (API keys, proxy settings) are set in the crontab.
What is Next
Section titled “What is Next”- Batch Operations — Combine scripting with batch patterns for large-scale automation
- GitHub Actions — Take your scripts to CI/CD
- Hooks and Automation — Trigger scripts automatically via hooks