Appearance
Print Mode -- Your First Real Task
Print mode is Claude Code's one-shot engine. You give it a task, it runs to completion, and it prints the result -- no interactive back-and-forth, no approval prompts, no waiting for your input. This is the mode you'll use in scripts, CI/CD pipelines, cron jobs, and anywhere you want Claude Code to do one thing and report back.

What you'll learn
- Print mode is the fire-and-forget path:
claude -p "your task"runs autonomously and exits when done --allowedToolsand--disallowedToolscontrol exactly which tools Claude Code can use, narrowing the blast radius for automated tasks--max-turnsputs a hard cap on the tool-calling loop, preventing runaway sessions in scripts--output-format jsonorstream-jsonmakes Claude Code's output machine-readable for piping into other tools
The problem
You have a task that needs to happen every day: check the logs for errors, extract the relevant lines, and write a summary. You could do it by hand. You could write a bash script. Or you could give Claude Code a one-line command and get the result in seconds.
The problem with using interactive mode for automation is that it waits for you. Every command needs approval, every turn pauses for input, and the session stays open. Print mode solves this: it runs the task, uses the tools it needs (within the bounds you set), and exits. It's Claude Code as a pipeline stage, not a conversation partner.
Options & when to use each
| Flag | What it does | When to use it |
|---|---|---|
claude -p "..." | Run in print mode, exit when done | The default for one-shot tasks |
--max-turns N | Cap the tool-calling loop at N turns | Prevent runaway sessions. Start with --max-turns 10 and raise it if the task legitimately needs more steps |
--allowedTools "Read,Edit" | Only allow specific tools (comma-separated) | When you want Claude Code to read files but not modify them, or run commands but not edit. Use --disallowedTools for the inverse |
--output-format json | Machine-readable JSON output | Piping results into jq, another script, or a logging system |
--output-format stream-json | Stream JSON events as they happen | Monitoring progress of a long-running task in real time |
--bare | Suppress formatting, just the raw result | Piping output directly into a file or another command |
--dangerously-skip-permissions | Skip all permission prompts | Only for fully trusted, automated environments. Understand what you're skipping before using this |
--permission-mode | Set the permission mode for the session | acceptEdits auto-approves file edits, bypassPermissions skips everything, default prompts for each |
--max-budget-usd | Set a spending cap in USD | Prevent surprise bills in automated runs. Claude Code stops when the budget is reached |
--model | Override the default model | Experiment with different models for specific tasks |
--effort | Set the reasoning effort level | Higher effort = more thorough but slower and more expensive |
Build it
Step 1: Run your first print mode task
Execute a single command using the -p flag. The agent processes the prompt, executes the necessary tool calls, and returns the final output immediately.
bash
claude -p "What files in the current directory were modified in the last 24 hours? Use find with -mtime, output as a plain list."Claude Code runs the find command, processes the output, and returns the result. No interactive prompts, no approval requests. It runs and exits.
Step 2: Control which tools are available
Not every one-shot task needs full filesystem access. Use --allowedTools to narrow the scope:
bash
# Read-only: can read files and run shell commands, but can't edit
claude -p "Check all Python files in src/ for syntax errors. Use python -m py_compile on each file." \
--allowedTools "Read,Bash"You can restrict the agent to edit operations only. This ensures no unexpected shell commands run during refactoring tasks.
bash
# Edit only: can read and write files, but can't run arbitrary commands
claude -p "Rename all instances of 'old_function' to 'new_function' in src/*.py" \
--allowedTools "Read,Edit"Alternatively, define what the agent cannot do. Use a blacklist approach when you want broad access but need to block specific, high-risk tools.
bash
# Disallow specific tools instead of allowing a whitelist
claude -p "Analyze the codebase structure and report the main entry points" \
--disallowedTools "Bash"The tool names are case-sensitive: Read, Edit, Write, Bash, Glob, Grep, WebSearch, WebFetch, Task, NotebookEdit, TodoWrite.
Step 3: Cap the turns to prevent runaway sessions
Enforce a maximum number of steps the agent can take. This acts as a circuit breaker for automated processes that might otherwise get stuck in a loop.
bash
# A task that should be simple -- cap it at 5 turns
claude -p "Check if there are any TODO comments in src/*.py and report them" \
--max-turns 5If the task needs more turns than the cap, Claude Code stops and reports what it completed. This is critical for cron jobs and CI/CD -- you don't want a loop running indefinitely because the model got confused.
Step 4: Get machine-readable output
Format the output as JSON for programmatic consumption. You can pipe this structured data directly into downstream utilities.
bash
# JSON output for piping into other tools
claude -p "Count the lines of code in each Python file in src/" \
--output-format json | jq '.result'For longer tasks, use the streaming JSON format. This emits events as they occur so you can track progress in real time.
bash
# Stream JSON for real-time monitoring
claude -p "Run the test suite and report failures" \
--output-format stream-jsonWith --output-format json, the entire response is a single JSON object. With stream-json, you get a stream of JSON events as the task progresses -- useful for long-running tasks where you want to see intermediate results.
Step 5: Run a real task -- not a demo
Assign a complex goal that requires synthesis. The agent manages the intermediate steps and aggregates the final result autonomously.
bash
# Find all Python files without docstrings, count them, and report the top 5
# modules by line count that are missing docstrings
claude -p "Find all Python files in the current directory tree that define functions
or classes without docstrings. Count them per file. Report the top 5 files
by number of missing docstrings. Use grep, find, and wc." \
--max-turns 10 \
--allowedTools "Read,Bash,Glob,Grep"This is a genuine task: it requires multiple tool calls, conditional logic, and a structured summary. Claude Code reads files, searches for patterns, counts results, and reports. It's not a hello-world.
Step 6: Combine print mode with shell scripting
Integrate the agent into standard Unix pipelines. Use the --bare flag to strip markdown formatting from the output.
bash
# Pipe Claude Code's output into another command
claude -p "Generate a list of all unique import statements in src/*.py" --bare | sort | uniq -c | sort -rnEmbed the agent directly into your bash scripts. You can use its exit codes and output strings to drive conditional logic.
bash
# Use in a script with error handling
#!/bin/bash
result=$(claude -p "Check if the API server on localhost:3000 is responding" --max-turns 3 --bare)
if echo "$result" | grep -q "not responding"; then
echo "API server is down" | mail -s "Alert" admin@example.com
fiWhat goes wrong
| Mistake | How you notice it | The fix |
|---|---|---|
| Print mode keeps running and never exits | The command hangs, no output for minutes | Add --max-turns. Start with 10. If the task legitimately needs more, raise it. If it's hitting the cap without finishing, the task might be too broad -- break it into smaller pieces |
| Claude Code can't read files because tools are restricted | Error: "Tool X is not allowed" | Check your --allowedTools list. If you need to read files but only allowed Bash, add Read to the list |
| JSON output is too verbose for piping | jq parses it but the structure is complex | Use --bare for raw text output when you're piping to another command. Use --output-format json only when you need structured data |
| Claude Code makes edits you didn't expect | Files changed without approval | Print mode with --dangerously-skip-permissions runs without asking. For safety, use --allowedTools "Read,Bash" to disable edits, or use --permission-mode acceptEdits for finer control |
| Budget blown on an automated task | Cloud bill is higher than expected | Set --max-budget-usd on every automated run. Claude Code v2.x tasks typically cost cents, but a runaway loop with a large model can add up |
| Print mode output is truncated in logs | Only the first few lines of output are captured | Use --output-format stream-json and redirect stderr to a log file: claude -p "..." 2>claude.log |
Confirm it worked
Verify your print mode configuration with a multi-tool prompt. Check that both plaintext and JSON formats render properly.
bash
# 1. Run a constrained print mode task that exercises multiple tools
claude -p "Find all Markdown files in the current directory tree. Count them.
Report the total and the 3 largest files by line count. Use find and wc." \
--max-turns 8 \
--allowedTools "Read,Bash,Glob,Grep"
# 2. Verify the output is actionable (actual file names and line counts, not a refusal)
# 3. Run the same task with JSON output
claude -p "Count Markdown files in the current directory tree" \
--max-turns 5 \
--output-format json
# 4. Verify the JSON is valid and contains the resultIf the first task returns real file names and line counts and the second returns valid JSON, print mode is working correctly. You can now use Claude Code as a pipeline stage.
Next: Interactive Mode -- the REPL, slash commands, and the permission system for when you want a conversation.