Non-interactive mode: claude -p
The -p (print) flag tells Claude Code to run a single task headlessly and exit — no REPL, no prompts to attend to. You hand it a task, it gathers context, takes action, and returns. That makes it composable with everything else in your shell.
# Run a single task non-interactively, then exit
claude -p "translate new strings into French and raise a PR" --no-interactive
# Pipe input straight into the prompt
echo "function validateEmail(email) { return true; }" | claude -p "add proper email validation"
# Fan a list of files into one task
find src -name "*.js" | claude -p "convert each file to TypeScript"
Mental model: Anything on stdin becomes part of the context; the quoted string is the instruction. Claude treats the two together as one task.
Shell integration patterns
Because Claude reads stdin, it slots neatly into existing pipelines. Treat it as the "intelligence" stage between two dumb commands.
# Analyze logs for anomalies
tail -200 /var/log/app.log | claude -p "identify any errors or anomalies and summarize"
# Security review on the diff against main
git diff origin/main --name-only | claude -p "review changed files for security vulnerabilities"
# Generate release notes from the git log
git log v1.0.0..HEAD --oneline | claude -p "write release notes grouping changes by type"
# Bulk rename following new conventions
ls src/components/ | claude -p "rename each file from PascalCase to kebab-case, output rename commands"
Structured output for programs
Prose is great for humans and terrible for scripts. --output-format json gives you a machine-parseable envelope you can feed to jq, store, or branch on. For long-running tasks, --stream emits results incrementally so a wrapping process can react as work lands.
# JSON output for programmatic parsing
claude -p "list all TODO comments in src/" --output-format json
# Pipe straight into jq
claude -p "list all TODO comments in src/" --output-format json | jq '.result'
# Streaming output for long tasks
claude -p "refactor all authentication code" --stream
Scheduling and loops
Once Claude is a one-shot command, you can run it on a clock or in a polling loop — no human in the seat. For always-on cloud scheduling without maintaining your own cron host, see Routines.
In-session loop
The /loop command repeats a prompt within a CLI session — ideal for polling a build or a deploy until it changes state.
Cron jobs
Wrap claude -p in a crontab line for nightly audits, dependency scans, or report generation.
CI/CD steps
The same command becomes a pipeline step — covered in depth in the Advanced track CI/CD lesson.
# crontab -e — run a nightly dependency audit at 2am
0 2 * * * cd /srv/app && claude -p "run nightly dependency audit and open GitHub issues for vulnerabilities"
Error handling in scripts
In automation you must assume tasks can fail. Claude Code sets an exit code, so wrap it in the same defensive patterns you would any other command — check $?, capture output, and fail loudly.
#!/bin/bash
result=$(claude -p "fix the failing tests" --no-interactive)
if [ $? -eq 0 ]; then
echo "Tests fixed: $result"
else
echo "Claude Code failed: $result" >&2
exit 1
fi
Practice: the automated test-fix loop
Combine everything above into one self-healing script. The flow is a complete agentic loop expressed in bash: run tests, hand failures to Claude, apply the fix, re-run, and commit only on green.
Run the test suite and capture failures.
Pipe the failure output to claude -p.
Let Claude apply the fix in place.
Re-run the tests to confirm.
Commit if and only if everything passes.
Automation FAQ
What does the claude -p flag do?
The -p (print) flag tells Claude Code to run a single task headlessly and exit — no REPL and no prompts to attend to. You hand it a task, it gathers context, takes action, and returns, which makes it composable with everything else in your shell.
How do you pipe data into Claude Code?
Because Claude reads stdin, anything you pipe in becomes part of the context while the quoted string is the instruction. You can pipe logs, git diffs, file lists, or git log output into claude -p — for example tail -200 app.log | claude -p "identify any errors and summarize" — and Claude treats the input and instruction together as one task.
How do you get machine-readable output from Claude Code?
Use --output-format json to get a machine-parseable envelope you can feed to jq, store, or branch on. For long-running tasks, --stream emits results incrementally so a wrapping process can react as work lands instead of waiting for the whole task to finish.
Can you schedule Claude Code to run automatically?
Yes. Once Claude is a one-shot command you can run it on a clock or in a polling loop. Wrap claude -p in a crontab line for nightly audits, dependency scans, or report generation; use the /loop command to repeat a prompt within a session; or drop the same command into a CI/CD pipeline step.
How do you handle errors when scripting Claude Code?
Assume tasks can fail. Claude Code sets an exit code, so wrap it in the same defensive patterns you would any other command: check $? after the run, capture the output, and fail loudly with a non-zero exit so the surrounding automation stops rather than silently continuing on a bad result.
Quick summary
claude -pruns a single task headlessly so Claude behaves like any Unix command- Pipe logs, diffs, file lists, and git output into Claude as context
--output-format jsonand--streammake output machine-parseable- Schedule with cron and guard with exit-code checks for reliable automation