Claude Codeの-pオプションは
「文書生成」向きかも

  • Claude Codeの-pオプションは非対話的な実行モードで、ファイルへの書き込みを自動では行いません。
  • 出力をリダイレクトしてコードを生成しようとすると、Markdownのコードブロック記法がそのまま残るため、そのままでは実行できません。
  • テキストの要約や翻訳など文書を扱う用途では、Markdown記法が邪魔にならないため相性がよいです。
  • 同じ単発プロンプト実行の仕組みでも、OpenAIのcodex execがソフトウェア開発の自動化を前提とした設計なのに対し、claude codeの-pオプションは自然言語変換というフィルタコマンドとしての使い勝手を優先した設計になっているようです。

関連記事

1. ファイルへの書き込みは明示的に止まった

Claude Codeには、対話モードを使わずにコマンドラインから直接プロンプトを実行できる-p(print)オプションがあります。

どう動くのか気になって、じゃんけんゲームのPythonスクリプトを書き換えさせてみました。

まず、コードを書き換えてファイルを保存するように指示してみました。

$ claude -p "janken.pyをRustに書き換えて、リネームして保存し直して"Code language: JavaScript (javascript)

結果は、書き込みできず。

1. ファイルへの書き込みは明示的に止まった
書き込みが許可されませんでした。
ファイルの保存先や名前に希望はありますか?

この動作は、好印象でした。
-pオプションは非対話的な実行モードで、スクリプトや自動化パイプラインから呼び出すことを想定しています1
そういった文脈でAIが勝手にファイルを書き換えないのは、わかりやすいです。

1.1. リダイレクトで保存すると、コードブロックが混入した

では、コードをどうやって生成すればいいのか。
今度はコードを標準出力に出し、シェルのリダイレクトでファイルに書き出してみました。
リダイレクトとは、コマンドの出力をそのままファイルに流し込む操作です。

$ claude -p "janken.pyをCommon Lispに書き直してコードだけを出力して" > janken.lispCode language: JavaScript (javascript)

できあがったjanken.lispを確認すると、ちょんと気になる点が。
Markdownのコードブロック記法、バッククォート3つで囲む書き方がそのまま残っていたのです。

1.1. リダイレクトで保存すると、コードブロックが混入した
(defvar *hands* #("グー" "チョキ" "パー"))
...
(main)Code language: PHP (php)

囲み記法が入っているため、このままsbcl --script janken.lispとして実行することはできません。

実際に機能するコードを直接生成させたいなら、今のところsedなどのテキスト処理の一工夫が要ります2

2. Claude CodeはMarkdownを返す

Claude Codeは対話モードでも-pモードでも、内部的にはMarkdownで整形された出力を返すように動いています。

対話モードでは端末がMarkdownをレンダリングするので見た目はきれいですが、リダイレクト先のファイルに流すとその書式指定そのものが文字として残ります3

「コードだけを出力して」という指示は意図が伝わっているように思えますが、出力フォーマットの制御としては不十分なのでした。

2.1. -pオプションが得意なこと、苦手なこと

この2つの実験から、-pオプションの特性が少し見えてきます。

ファイルシステムへの変更には許可が必要で、出力をリダイレクトしてファイルを作る方法もありますが、「書き換えてそのまま保存」というワンライナーな自動化には向きません。

ただし、要約・翻訳・説明文の生成といった「テキストを書かせる」用途であれば、出力をリダイレクトしてもMarkdown記法は邪魔になりません。

ということで、ドキュメント生成やコードレビューコメントの自動作成など、文書を扱うパイプラインとの相性は良さそうです4

あるいは、コード生成を自動化したい場合は、対話モードでファイル書き込みまで一緒に任せるのが現実的な選択になりそうです。

3. codex execclaude -p、設計思想の違い

同じ「単発のプロンプトを与えてAIエージェントを動かす」仕組みとして、OpenAIが提供するCodex CLIのexecサブコマンドと比べると、設計の方向性がやや異なることに気づきます。

codex exec vs claude -p:設計思想の違い codex exec CI/CD組み込みを前提 Gitリポジトリ内での実行を想定 デフォルト:読み取り専用 –sandbox workspace-write で許可 起動オプションで権限を宣言 何ができるかを明示する設計 claude -p Unixコマンドとしての統一性 標準出力に結果を流す パイプ・リダイレクトで組み合わせ 他コマンドと連携しやすい FS変更は呼び出し側が制御 フィルタとして振る舞う設計 自動化ワークフロー向き CI/CDパイプラインに組み込む場合 文書・テキスト変換向き シンプルなパイプラインで使う場合

codex execは、CIパイプラインやスクリプトへの組み込みを明確に意識して作られています。
Gitリポジトリ内での実行を前提とし5、デフォルトでは読み取り専用のサンドボックスで動きます。
ファイルへの書き込みや変更を許可したい場合は、--sandbox workspace-writeのように明示的なフラグが必要で、「何ができるか」を起動時のオプションで宣言する設計になっています。

一方、claude -pはどちらかというとUnixコマンドラインツールとしての統一性を意識しています。
標準出力に結果を流し、リダイレクトやパイプで他のコマンドと組み合わせられる、そういう「素直なコマンド」として振る舞おうとしているようです。
-pモードでファイルシステムを変更するなら、それは呼び出し側が別途制御すべきという考え方に見えます。

つまり、codex execはソフトウェア開発の自動化や自動化ワークフローを正面から狙っており、claude -pはUnixのフィルタコマンドとして柔軟に使えることを優先している印象です。
処理の自動化を組むならcodex execのほうが有効で、文書生成やテキスト変換のパイプラインならclaude -pのほうがシンプルに書けます。

-pオプションはまだ使い方を探っている段階ですが、文書生成のパイプラインとしての可能性は感じています6

  1. Anthropic の公式ドキュメントでは -p モードを「ヘッドレスモード(headless mode)」とも呼んでいました。現在は「CLIモード」と改称されていますが、-p フラグの動作は変わりません。 – Run Claude Code programmatically – Claude Code Docs
  2. --output-format text を明示しても Markdown の書式は残ります。コードのみを取り出したい場合は sed '/^```/d' などで囲み記法の行を削除する後処理が現実的です。 – Common workflows – Claude Code Docs
  3. Claude Code CLI でMarkdownがそのまま表示される問題は GitHub の Issue でも報告されており、ターミナル上でレンダリングするよう求める feature request が上がっています。 – [FEATURE][CLI] Markdown renderer support in Claude Code CLI · Issue #13600 · anthropics/claude-code
  4. -p モードはデフォルトで最大10ターンまでエージェントのループを実行します。--max-turns フラグで上限を変更でき、CI 環境では無限ループ防止のために明示的に設定することが推奨されています。 – Headless Mode and CI/CD – Tutorial | SFEIR Institute
  5. codex exec はデフォルトで Git リポジトリ外での実行を拒否します。リポジトリ外で使いたい場合は --skip-git-repo-check フラグで回避できますが、公式ドキュメントは「環境が安全と確認できる場合のみ使用すること」と注意しています。 – Non-interactive mode – Codex CLI Docs
  6. -p モードの活用事例をコミュニティに募った GitHub Issue では、PR 説明文の自動生成・changelog 作成・コードレビューコメントの自動化などが多く挙げられています。 – What are you using print mode (claude -p) for? · Issue #762 · anthropics/claude-code