💻

Claude Code 実践検証 Day 9|Headlessモードの設定反映と終了コードの謎

に公開

Claude Codeの-pオプション、使ってますか?

ワンライナーでClaude Codeにタスクを投げられる機能です。自動化スクリプトでの活用を想定した「Headlessモード」ですね。

claude -p "このコードのバグを修正して"

公式ドキュメントを読むと、これで自動化できそうな印象を受けます。でも実際にやってみると…「あれ?設定反映されてない?」「エラーなのに終了コード0?」みたいな事態に遭遇するんですよね。

私も最初、思うように自動化できず調査が難航しました。


公式ドキュメントの説明

まずは公式が何を言っているか整理しておきましょう。

公式ドキュメント(CLI Usage)によると、Headlessモードでは以下のオプションが使えます。

基本オプション

オプション 説明
-p, --print プロンプトを送信し、応答を出力して終了
--output-format 出力形式(text/json/stream-json)
--max-turns エージェントのターン数上限
--allowedTools 使用可能なツールの制限
--dangerously-skip-permissions 承認プロンプトをスキップ

設定ファイル

  • CLAUDE.mdはプロジェクトルートから読み込まれる
  • settings.local.jsonの設定が適用される
  • Hooksも設定すれば発火する

…と、公式にはこう書いてあるんですが。


検証したい観点

自動化スクリプトで実際に使おうとすると、いくつか疑問が出てきます。

疑問1:Hooksは本当に発火するのか?

対話モードでは、PreToolUseやPostToolUseでスクリプトを実行できます。ログを取ったり、特定の操作を禁止したり、便利ですよね。

でもHeadlessモードではどうなんでしょう。

「対話なしで動く」のがHeadlessモードの特性です。ということは、Hooksの発火タイミングも変わってくる?そもそも発火する?公式には明確な記載がないんですよね。

疑問2:終了コードはエラー時に0以外になる?

自動化スクリプトでは終了コードが生命線です。

claude -p "テストを実行" || exit 1

こういう書き方をしたいわけですが、パーミッションエラーやmax-turns制限に達した場合、ちゃんと非0で終了してくれるんでしょうか。

「失敗したのに終了コード0」だと、スクリプトが正常終了扱いになってしまいます。これ、かなり怖いですよね。

疑問3:Windows環境でどのシェルを使うべき?

既存のClaude Code記事はMac/Linux前提が多いです。でもWindows環境でも使いたい人はいるはず。

PowerShellから呼び出す場合と、Git Bashから呼び出す場合で差異があるか。日本語出力は文字化けしないか。確認しておきたいポイントです。

疑問4:設定ファイルは読み込まれるのか?

対話モードでは確実に読み込まれるCLAUDE.mdやsettings.local.json。

Headlessモードで起動した場合も同じように読み込まれるのか。permissions.allowやpermissions.denyは機能するのか。この辺の一貫性が気になります。

疑問5:スラッシュコマンドは使えるのか?

/compactでコンテキストを圧縮したり、カスタムコマンド/my-commandを呼び出したり。対話モードでは便利な機能ですよね。

ただ、公式ドキュメントには「Control Claude's behavior during an interactive session with slash commands.」と書いてあります。「interactive session」と明記されている以上、Headlessモードでは非対応と考えるのが妥当でしょう。

これについては検証しません。仮に動作したとしても、公式がサポートを保証していない使い方になるので。


検証項目の一覧

明日の検証では、以下を確認します。

項目 検証内容 判定基準
設定ファイル読み込み CLAUDE.md、settings.local.jsonの反映 対話モードと同じルールが適用されるか
Hooks発火 PreToolUse/PostToolUseの発火有無 ログファイルが生成されるか
終了コード エラー時(deny、max-turns等)の終了コード 非0で終了するか
シェル比較 Git Bash vs PowerShellの動作差異 日本語出力、エラー処理の差
出力形式 json、stream-jsonの動作 コスト情報、エラー情報が取得できるか
タイムアウト 長時間実行時のハング回避 timeoutコマンドとの併用可否

検証環境

今回の検証環境は以下の通りです。バージョンによって挙動が変わる可能性があるので、明記しておきます。

項目
OS Windows 11 Pro
Claude Code v2.0.60
Git Bash Git for Windows付属
PowerShell 7.x(UTF-8設定済み)

シェルは主にGit Bashを使用しますが、PowerShellとの比較検証も行います。


明日の予告

検証は完了しています。結果を先に言うと、公式ドキュメントとの差異がいくつか見つかりました

特に大きかったのは2点。

  1. HooksはHeadlessモードでは発火しない
  2. 終了コードは常に0(エラーでも!)

自動化スクリプトを書こうとしている方、この2点は要注意です。回避策も含めて、明日詳しく解説します。

Windows環境でのシェル選択についても、明確な結論が出ました。PowerShellでの日本語出力は…ちょっと残念な結果でしたね。

Headlessモードをスクリプトから呼び出そうとしている方、ぜひ参考にしてください。


シリーズ情報

  • シリーズ名:Claude Code 実践検証ガイド 2025
  • 著者:Akira
  • 検証環境:Windows 11 / Git Bash / Claude Code v2.0.60

次回:Day 10「Headless検証結果:Hooks無効、終了コード常に0の衝撃」

Discussion