Claude Media
respondToBashCommandsで!コマンド出力への自動応答を止める

respondToBashCommandsで!コマンド出力への自動応答を止める

!で打ったbashコマンドの出力にClaudeが自動で応答する既定動作は、respondToBashCommandsをfalseにすると止まります。v2.1.186での変更点と設定手順、無効化が向く場面をまとめます。

Claude Codeの入力欄で!から始めてbashコマンドを打つと、実行結果が会話に取り込まれるだけでなく、Claudeがその出力を見て自動で応答するようになりました。この既定動作を止めて、出力を文脈に入れるだけの従来の挙動に戻す設定がrespondToBashCommandsです。falseにすると、コマンドを何本か続けて打ってからまとめて質問する、という使い方に戻せます。

入力欄の先頭に!を置いてEnterすると、そのシェルコマンドを直接実行する「shell mode」に入ります。git statusやlsのようなコマンドをその場で走らせる機能で、Claudeによる解釈も承認も挟まずに実行されます。実行結果はセッションに追加され、Claudeがその出力に応答します。respondToBashCommandsが切り替えるのは、この最後の「Claudeが応答する」部分だけで、shell mode自体はv2.1.186より前からある機能です。

respondToBashCommandsとは何を切り替える設定か

respondToBashCommandsは、!プレフィックスで実行したシェルコマンドの出力に対して、Claudeが自動で返信するかどうかを切り替えるBoolean設定です。既定値はtrueで、たとえば! npm testを打つと、2つ目のプロンプトを書かなくてもClaudeが失敗の理由を説明します。falseにすると、出力は会話の文脈に追加されるだけになり、Claudeからの返信は起きません。

スコープはAny fileです。設定リファレンスはこの4つをUser(~/.claude/settings.json)・Project(.claude/settings.json)・Local(.claude/settings.local.json)・Managed(組織が配布する設定)と呼び、Any fileはこの4種類のどれに書いても読み込まれることを意味します。複数のファイルに同じキーを書いた場合は、優先順位の高いファイルの値がそのまま使われます。

v2.1.186で既定動作がどう変わったか

この自動応答はv2.1.186で追加された挙動です。インタラクティブモードの解説にも「v2.1.186より前のshell modeは、出力を文脈に追加するだけで応答しなかった」と書かれています。respondToBashCommandsはこの新しい既定を打ち消すための設定として、同じv2.1.186で用意されています。

バージョン!コマンド出力への挙動
v2.1.185以前!コマンド出力への挙動出力は文脈に追加されるだけ。Claudeからの応答はない
v2.1.186以降(既定)!コマンド出力への挙動出力を見てClaudeが自動で応答する
v2.1.186以降 + respondToBashCommands: false!コマンド出力への挙動v2.1.185以前と同じ、文脈追加のみの挙動

CHANGELOGにはこの変更が次のように記載されています。

! bash commands now trigger Claude to respond to the output automatically; set "respondToBashCommands": false in settings.json to keep the previous context-only behavior

つまりfalseは新機能を無効化する設定ではなく、意図的に旧挙動へ戻すためのオプトアウトです。アップデート後に「コマンドを打つたびにClaudeが割り込んでくる」と感じた場合は、settings.jsonにこの1行を足すだけで解消します。

自動応答は1回ごとのプロンプトと同じコストがかかる

インタラクティブモードの解説には、自動応答の費用についての記述があります。応答にかかるコストは、通常のプロンプトを1回送ったときと同じです。!コマンドは自分で実行するぶん軽い操作に見えますが、trueのままなら1本打つたびにモデルへのリクエストが1回発生します。

軽い確認コマンドを並べるセッションでは、この積み重ねが無視できなくなります。!ls→!cat package.json→!git log -5のように3本続けると、3回ぶんの応答が会話に残り、その都度の解釈や提案も文脈に積まれます。単なる下調べのつもりで打った!コマンドが多いセッションほど、意図しない提案が混ざりやすくなります。まとまった調査を!で済ませてから相談したい場合は、この点がfalseを選ぶ理由になります。

respondToBashCommands: falseにする設定手順

手順

falseにして反映を確かめるまで

  1. 1

    書き込む設定ファイルを選ぶ

    個人の全プロジェクトで戻すなら~/.claude/settings.json、特定のリポジトリだけならコミット対象の.claude/settings.jsonか、コミットしない.claude/settings.local.jsonです。組織全体で強制するなら、managed設定に書くと、ユーザー設定やプロジェクト設定でtrueに戻されても上書きされません。

  2. 2

    キーを追加する

    対象のsettings.jsonにrespondToBashCommandsをfalseで書きます。

  3. 3

    新しいセッションで確かめる

    保存後は新しいセッションを開き、!コマンドを1つ打ちます。出力だけが表示されて、Claudeの発言が続かなければ反映されています。

{
  "respondToBashCommands": false
}

確認用のコマンドは何でも構いません。

!git status

trueのままなら、この直後にClaudeが変更内容についてコメントを返します。

ファイルを書き換えずに、1回のセッションだけ試す方法もあります。v2.1.289のclaude --helpには、次のオプションが載っています。

--settings <file-or-json>   Path to a settings JSON file or a JSON
                            string to load additional settings from

JSON文字列も渡せるので、claude --settings '{"respondToBashCommands": false}'で起動すれば、そのセッションだけfalseで動きます。設定リファレンスの優先順位では、コマンドラインの--settingsはmanaged設定の次に強く、project localやUserのファイルより優先されます。

trueとfalseの違いは、出力が消えるか残るかではありません。どちらの設定でも!コマンドの出力は会話の文脈に追加され、後続のやり取りでClaudeが参照できます。変わるのは、その追加のタイミングでClaudeが新しい発言(会話上のターン)を作るかどうかだけです。

どんな運用で無効化する意味があるか

自動応答が効くかどうかは、!コマンドをどう使っているかで決まります。

くらべる

trueのまま使う人とfalseにする人

1本ごとに会話したい

trueのまま

コマンドを1つ打つたびに次の指示を考える対話運用や、ペアプロ的にClaudeと結果をすり合わせる使い方です。出力を見た直後にClaudeが反応するので、確認と次の一手が一続きになります。

読み終えてから聞きたい

falseにする

git statusやgit diff、ログの確認を連続で打ってから、まとめて1つ質問する使い方です。1コマンドごとに応答が挟まらないので、読み進めるテンポが崩れません。

判断の軸は、!コマンド1本ごとに通常のプロンプト1回ぶんのコストを払ってでも、Claudeの反応が欲しいかどうかです。

permissions系の設定とは別物

respondToBashCommandsは、Bashコマンドを実行してよいかどうかの確認フローには関与しません。permissions.allowやpermissions.ask、あるいはサンドボックス化されたコマンドを確認プロンプトなしで実行するsandbox.autoAllowBashIfSandboxedは「コマンドを実行する前に確認するか」を決める設定です。respondToBashCommandsは「実行した後の出力にClaudeが応答するか」を決める設定です。前者を厳しくしたまま後者をfalseにしても、コマンドの実行自体が止まったり確認が増えたりすることはありません。

!で打ったコマンドは、そもそもこれらの確認フローの外にあります。インタラクティブモードの解説では、shell modeはClaudeによる解釈も承認も必要としないと説明されています。さらにサンドボックスの解説によると、ほとんどのセッションでは!で打ったコマンドはサンドボックスの外で実行されます。サンドボックスが掛かるのはClaudeが実行するコマンドで、自分で打ったコマンドには及びません。例外は、バックグラウンドセッションのstrict sandbox modeと、LinuxでCLAUDE_CODE_SUBPROCESS_ENV_SCRUBを設定したセッションです。

この切り分けは、トラブルシューティングの順番にも影響します。「!コマンドを打っても何も起きない」という相談は、実際には2種類に分かれます。

切り分け

何も起きないときの切り分け

  • コマンドが実行されない

    コマンド自体が走っていない、または確認プロンプトで止まっているケースです。permissions関連の設定やサンドボックスの設定を見直します。

  • 出力は出るがClaudeが黙っている

    コマンドは実行されて出力も表示されるのに、Claudeからの発言だけが来ないケースです。respondToBashCommandsがfalseになっていないかを確認します。

自動承認とサンドボックスの組み合わせはautoAllowBashIfSandboxedの記事で、複数行コマンドの自動承認が効かない問題は複数行コマンドの自動承認で扱っています。「新機能の既定動作を設定でオプトアウトする」という型自体は、スラッシュコマンドとSkillを丸ごと無効化する--disable-slash-commandsとも共通しています。

shell modeで知っておきたい周辺の操作

shell modeには、応答の有無とは別に覚えておくと役立つ操作があります。インタラクティブモードの解説に載っているものを挙げます。

  • Ctrl+B: 実行に時間のかかるコマンドをバックグラウンドに回します
  • Tab: 途中まで打った入力を、そのプロジェクトで過去に打った!コマンドから補完します
  • Escape、Backspace、Ctrl+U(空の入力欄で): shell modeを抜けます
  • !で始まるテキストを空の入力欄に貼り付けると、自動でshell modeに入ります

Claudeが作業している最中でも、!コマンドは通常のメッセージと同じようにキューに積めます。

書きかけのコマンドを守りたいときはCtrl+Sが使えます。実行中の処理がなければ、Ctrl+Cは1回目で入力欄を空にし、空の状態でもう一度押すとClaude Codeが終了します。長いコマンドを書いている途中でCtrl+Cを押すと入力が消えるので、代わりにCtrl+Sで退避します。テキストが入った状態で押すと入力を退避して空にし、空の入力欄でもう一度押すと、カーソル位置や貼り付けた内容ごと、shell modeのまま復元されます。

よくあるつまずき

respondToBashCommandsをfalseにしても、Claudeがタスクの中で自分の判断でBashツールを呼び出す通常のエージェント動作は変わりません。この設定が対象にするのは、あくまで入力欄で!から始めてユーザーが直接打ったシェルコマンドの出力だけです。Claudeがコード修正の途中でテストコマンドを実行し、その結果を踏まえて次の作業を進める流れは影響を受けません。「Bashの実行結果にClaudeが反応しなくなった」ように見えても、!コマンドの出力なのかエージェントのBashツール呼び出しなのかを、まず切り分けます。

もう一つつまずきやすいのが、複数の設定ファイルに同じキーを書いてしまうケースです。respondToBashCommandsはBoolean値なので、~/.claude/settings.jsonと.claude/settings.jsonの両方に異なる値を書いても合成はされず、優先順位の高い側の値だけが有効になります。設定ドキュメントの優先順位は、高い順にmanaged設定、コマンドライン(--settings)、project local、共有のproject、userです。falseにしたはずなのに応答が止まらないときは、これより上位のファイルや起動オプションにtrueが残っていないかを見ます。

配列で指定するキーは複数のスコープで値が結合されますが、Boolean値にそうした結合はありません。変更したファイルをメモしておくと、後から原因を探すときに楽です。

まとめ

割り込みなしで!コマンドを続けて打ちたいなら、~/.claude/settings.jsonにrespondToBashCommands: falseを1行足せば足ります。それでも応答が止まらないときは、上位のmanaged設定や--settingsにtrueが残っていないかを見ます。バージョンごとの変更点はClaude Code v2.1.186のリリースノートにあります。

この記事を共有:XはてブLinkedIn