Claude Codeの--execでシェルコマンドをバックグラウンド実行する
Claude Codeの--execフラグは、シェルコマンドをモデルを介さずPTY付きのバックグラウンドジョブとして起動する仕組みです。--bgとの組み合わせ方、管理コマンド、出力が5分で消える制約を扱います。
Claude Codeの--execフラグは、シェルコマンドをClaudeセッションとしてではなく、PTY(疑似端末)付きのバックグラウンドジョブとして起動します。claude --bg --exec 'pytest -x'のように使うと、モデルを一度も呼ばずにpytest -xだけが裏側で走ります。結果はagent viewの一覧に1行として現れます。
テストやビルドのような待つだけの処理を、Claudeへの依頼と同じIDと管理コマンドで扱いたいときに向く機能です。changelogによると、v2.1.154でagent viewの入力欄に! <command>と打つ形とあわせて追加されました。
待つだけの処理にClaudeを呼ぶ必要はあるか
claude --bgに指示文を渡すと、Claudeがそれを読んで調査や編集を行う対話セッションがバックグラウンドで始まります。--execを足すと、同じ--bgから始まりながら中身がまったく別物になります。
同じ--bgでも起動するものが違う
claude --bg 指示文
モデルが指示文を読んで作業します。会話はディスクに残り、終了後もclaude --resumeで参照できます。調査や修正のように、結果を解釈して次の手を打つ作業向きです。
claude --bg --exec コマンド
指定したコマンドだけが走り、モデルは呼ばれません。出力はメモリ上にあるだけで、終了から約5分で行ごと消えます。テストやビルドの完了待ちのような単発の処理向きです。
agent viewの公式ドキュメントは、シェルジョブがClaudeの代わりにコマンドを実行すると説明しています。出力もどのセッションにも送られません。
PTYとは、パイプでつないだだけのプロセスと違って、端末から実行されているように相手へ見せる仕組みです。素のシェルで叩いたときと同じ前提でコマンドが動くので、シェルで走らせるつもりだった処理をそのまま預けられます。
テストを1回走らせたいだけなのに「テストを実行して」とClaudeに頼むと、モデルが結果を読むぶんの待ち時間とやり取りが挟まります。逆に、結果を見てファイルを直したいなら、最初から--execではなく通常の--bgのほうが手数は少なく済みます。
起動して結果を読むまでの流れ
シェルから起動する形は、--bgと--execを並べるだけです。値のコマンドは1つの文字列として渡します。パイプやリダイレクトを含むときは、全体をクォートで囲んで1つの引数にします。
claude --bg --exec 'pytest -x'起動から結果の確認まで
- 1
起動してIDを受け取る
起動すると、短いIDと管理用のコマンドが出力されます。このIDは
~/.claude/jobs/<id>のディレクトリ名と同じで、通常のバックグラウンドセッションと共通です。 - 2
agent viewで行を探す
claude agentsを開くと、コマンドの最新の出力行をステータスにした行が並びます。複数のリポジトリで使っていて一覧が長いときは、claude agents --cwd <path>で指定ディレクトリ配下の行だけに絞れます。 - 3
終了後5分以内に出力を読む
行を選んで
Spaceで覗くか、Enterでアタッチするか、シェルからclaude logs <id>を叩きます。読む前に行が片付くと、出力は取り戻せません。
もう1つの起動経路はagent viewの入力欄です。先頭に!を付けると、その行はClaudeへのプロンプトではなくシェルコマンドとして扱われます。
!pytest -x!は入力欄でプレフィックスとして表示され、以降の文字列がそのままコマンドになります。Enterでジョブが始まり、シェルから--bg --execで起動した場合と同じ種類の行が一覧に加わります。
ビルドの結果を残したいときは、リダイレクトまでコマンドの一部として渡しておきます。
claude --bg --exec 'npm run build > /tmp/build.log 2>&1'--exec自体はログをディスクへ保存しません。保存が必要なら、コマンド側でファイルへ書き出す形にします。
起動したジョブを確認・停止するコマンド
管理に使うコマンドは、他のバックグラウンドセッションと共通です。
| コマンド | 用途 |
|---|---|
claude agents | 用途一覧を開き、ジョブの行を状態付きで確認する |
claude attach <id> | 用途ジョブの出力をこのターミナルで直接見る |
claude logs <id> | 用途アタッチせずに直近の出力だけ表示する |
claude stop <id> | 用途ジョブを止める(claude killでも同じ) |
v2.1.287のclaude attach --helpには、←で一覧に戻り、Ctrl+Zでシェルに戻るという説明が出ます。どちらで離れても、ジョブは動き続けます。
ジョブはagent viewやターミナルを閉じても止まりません。常駐のsupervisorプロセスがセッションとジョブの両方を保持しているためで、claude daemon statusで状態を見られます。
動作がおかしいときの手段として、claude daemon stop --anyはsupervisorとそれが抱えるセッション・ジョブをまとめて止めます。個別のジョブだけを止めたいならclaude stop <id>で足ります。--keep-workersを付けると、バックグラウンドのセッションを動かしたまま、次に起動するsupervisorへ引き継げます。
claudeをアップデートした直後は、動いているsupervisorが古いバージョンのままのことがあります。claude daemon statusは両者のバージョンの食い違いを警告し、claude daemon stop --anyで切り替えるよう案内します。
ジョブが一覧に出てこないときは、supervisor側のログが手がかりになります。v2.1.287のclaude daemon --helpには、claude daemon logsでデーモンのログを追えること、既定のログ先が~/.claude/daemon.logであることが載っています。Ctrl-Cで追跡を終えます。
実行中のコマンドに入力を送りたいとき
確認プロンプトで止まっているコマンドがあっても、アタッチせずに返事を送れます。行を選んでSpaceでpeekパネルを開き、返信を入力してEnterを押すと、コマンドの端末に入力として届きます。
Claudeのセッションでは、返信がちょうど/stopだと、届けられずにセッションそのものが止まります。シェルジョブでは違い、/stopもほかの文字列と同じく端末への入力として渡されます。ジョブを止めるにはclaude stop <id>を使います。
同じpeekパネルの操作でも、宛先がClaudeのセッションかシェルジョブかで意味が変わります。動いているセッションへの返信はメッセージキューに入り、応答を中断しません。
起動で止まるときの原因
--execは--bgと組み合わせて使うフラグで、v2.1.287のclaude --helpのオプション一覧には--execの行がありません。--bgの説明にも出てこないため、--helpだけを頼りにすると見落とします。公式のCLIリファレンスには--execの行があります。
-p(--print)を足すと、v2.1.198以降は起動前にエラーで止まります。
--bg and --print conflict: --print never starts the interactive session that `claude agents` attaches to, so the job would be unattachable. The prompt is the positional — drop --print: `claude --bg '<task>'`.v2.1.198より前は、アタッチできないジョブが黙って作られていました。スクリプトから呼ぶときは、先に--bg単体で起動できることを確かめてから--execを足すと切り分けやすくなります。
もう1つ、--bgは起動前に作業ディレクトリのワークスペース信頼を確認します。まだ信頼していないディレクトリでは、ターミナルなら確認ダイアログが出ます。ダイアログを出せないスクリプトの中では、Workspace not trustedエラーで終了します。
出力が消えるまでの5分
シェルジョブの出力は、ディスクに書き込まれずメモリ上にだけ保持されます。
シェルジョブの出力が残る期間
- 起動〜実行中最新の1行が行に出る
コマンドが動いている間は、行のステータスに最新の出力行が表示されます。5分のカウントはまだ始まりません。
- コマンド終了カウント開始
終了後の約5分は、
claude logs・claude attach・Spaceのpeekで出力を読めます。 - 終了から約5分後行と出力が消える
claude logsもclaude attachも、結果を返せなくなります。
tail -fのように自分では終了しないコマンドの行は、終了するまで残ります。一方で、長い処理を投げっぱなしにして戻ったら結果が消えていた、という事態は起こりえます。ファイルへのリダイレクトを付けておけば、行が消えても結果は残ります。
結果をどこまで残したいかで、起動の仕方は次のように分かれます。
- 終わったかどうかだけ分かればよい: 行のステータスに出る最新の出力行で足ります
- 出力を全部あとから読み返したい:
> /tmp/build.log 2>&1のようにコマンド側でファイルへ書きます - 実行中に確認プロンプトへ答えたい: peekパネルから返信を送ります
- 出力を読んで次の修正まで任せたい:
--execではなく通常の--bgで依頼します
再実行されない行と、末尾の&との違い
シェルコマンドの行は、Enterでもclaude attachでも再起動されません。再起動すると同じコマンドをもう一度実行してしまうためで、行のメッセージとclaude attachの出力の両方に、コマンドが再実行されない旨が出ます。
ファイルへ書き込むコマンドを再起動のつもりで動かすと、二重に実行されかねません。通常のセッションの行は、プロセスが終了していても、返信やアタッチで続きから再開されます。
ターミナルでコマンドの末尾に&を付ける方法と比べると、管理の手段が違います。&で裏に回したプロセスには、claude attachやclaude logsのような共通のコマンドがありません。いま何が動いているかを一覧で見る手段も、シェルのジョブ表以外にはありません。
--execのジョブはsupervisorが保持するので、ほかのセッションと同じ一覧に並び、同じIDで見られます。agent viewは、手元のシェル作業を一時的に預けておく場所としても使えます。
スクリプトや権限の設定と組み合わせるとき
claude agents --jsonでジョブの状態をスクリプトから読み取りたい場合は、claude agents --jsonでバックグラウンドセッションを操作するにスクリプト向けの詳細があります。agent view全体の常駐プロセス設計や状態アイコンの見方は、Claude Codeのagent viewにまとまっています。
--exec以外の起動時フラグで挙動を固定したい場合は、権限モードを起動時に決め打ちするClaude Codeの--permission-modeで起動モードを指定するや、使えるツールを起動時に絞り込むClaude CodeのallowedTools/disallowedToolsで起動時に権限を絞るもあわせて確認してください。