
Pipe a Build Log, Get a Root Cause: Four `claude -p` Patterns for Shell Scripts and CI
Chris Harper
3 min read
Aug 30, 2026 · 20:05 UTC
TL;DR: claude -p makes Claude Code behave like grep or jq — one prompt in, one result out, then exit. Four shell patterns you can use today.
The interactive TUI is the right tool for exploratory work. But for a repeated pipeline step — triage a build error, extract function names, review a diff before commit — you want a command that composes with the rest of your shell. claude -p is that command.
Pattern 1: Triage in one pipe
cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt
Stdin is read as context; output goes to stdout. Pipe in up to 10 MB (use a file path in the prompt for larger inputs). Exit code 0 on success, non-zero on failure — branch on it in scripts.
Pattern 2: A lint:claude step in package.json
{
"scripts": {
"lint:claude": "git diff main | claude -p \"you are a typo linter. for each typo, report filename:line then the issue. return nothing else.\""
}
}
Run with npm run lint:claude. Claude sees the diff without Bash permission to read git internals.
Pattern 3: Typed JSON output
claude -p "Extract the main function names from auth.py" \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
| jq '.structured_output'
--output-format json also includes total_cost_usd and a per-model breakdown — useful for tracking spend per invocation in CI without consulting the dashboard.
Pattern 4: Chained review sessions
session_id=$(claude -p "Review this codebase for performance issues" --output-format json | jq -r '.session_id')
claude -p "Now focus on the database queries" --resume "$session_id"
claude -p "Generate a summary of all issues" --resume "$session_id"
Each subsequent call continues the same conversation. --continue resumes the most recent session when you don't need to capture the ID.
Key flags to know
--bare: skips hooks, plugins, CLAUDE.md, and MCP servers — use in CI for reproducible, machine-agnostic runs. Will become the default for-pin a future release.--allowedTools "Bash,Read,Edit": auto-approves tools without prompting.--permission-mode acceptEdits: Claude writes files without asking; other shell commands still need an--allowedToolsentry.--append-system-prompt "...": add a reviewer role without a full session setup ("You are a security engineer. Review for vulnerabilities.").
Real limits
--baremode cannot use your Claude subscription OAuth; setANTHROPIC_API_KEYbefore running.- Stdin capped at 10 MB; reference a file path in the prompt for larger inputs.
- Background Bash tasks started during a
-prun are terminated about 5 seconds after the final result — don't rely on them for cleanup or post-processing. --restricted(strips command tools entirely) and-p(single-shot exit) are complementary, not synonyms: use--restrictedfor long-running CI agents that should not touch the network; use-pfor one-off pipeline steps that exit.
Sources: Run Claude Code programmatically — code.claude.com · Claude Code in CI/CD and Headless Automation — hidekazu-konishi.com · Claude Code Headless Scripting 2026 — StackNotice