◉CLAUDE LABEN
●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/Claude Code
⟐ Claude Code/2026-05-18中級

Claude Code の Bash ツールで cd や export が引き継がれない時の対処

Claude CodeのBashツールでcdやexportが次のコマンドに反映されないのは、1回ごとに独立したシェルで起動する仕様のためです。&&で1行に束ねる、絶対パスを徹底する、環境変数をインラインで渡す、CLAUDE.mdに置くなど、実務で使える5つの対処パターンを整理しました。

Claude Code265Bash5シェル3トラブルシューティング51自動化87

Claude Code に少し複雑なタスクを任せ始めると、ほとんどの方が一度はぶつかる症状があります。「cd some-dir を実行して、次の ls を叩いたら、なぜか元の作業ディレクトリで実行されている」という現象です。export FOO=bar も同じで、次のコマンドでは $FOO が空になっていることがあります。

私自身、Dolice Labs で 4 サイトの記事自動投稿パイプラインを Claude Code 主体で組み直していた 2026 年初頭、同じ落とし穴で半日近く溶かしました。原因が分かれば一行で済む話ですが、知らないと「Claude Code が壊れているのではないか」と疑い始めるので、最初に整理しておく価値はあると感じています。

症状 — cd した直後の ls が想定外の場所で動く

具体的には、こういう挙動です。

# 1 回目の Bash ツール呼び出し
cd /tmp/repos/claudelab.net
# 2 回目の Bash ツール呼び出し
ls
# → なぜかホームディレクトリの中身が返ってくる

export も同じ症状になります。

# 1 回目
export GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxx
# 2 回目
echo "$GITHUB_TOKEN"
# → 空文字

スクリプトファイルにして手元のターミナルで流すと普通に通るので、最初は「Claude Code 側のバグかも」と疑いがちですが、これは仕様通りの挙動です。

原因 — Bash ツールは 1 回ごとに独立したシェルで起動する

Claude Code(および Cowork mode の mcp__workspace__bash も同じです)は、Bash ツールの呼び出しごとに新しいサブプロセスとしてシェルを立ち上げます。つまり、1 回目の呼び出しが終わった瞬間にプロセスが破棄され、cd や export で変えた状態はすべて失われます。

私の手元では、Cowork 経由の bash ツールの説明にも「Each call is independent — no cwd/env carryover between calls. Use absolute paths.」と明記されており、Claude Code 本体の Bash ツールでも基本ポリシーは同じです。要するに、Claude Code の Bash は「実行履歴を共有しないリモートシェル」だと考えるのが一番近い感覚です。

ここを理解すると、対処方針はシンプルになります。「状態を次の呼び出しに持ち越そうとしない」ことを徹底すればよい、ということです。

対処 1 — && で 1 行のコマンドに束ねる

最も多用するパターンです。cd してから何かを実行する場合は、必ず同じ Bash 呼び出しの中で && で連結します。

# NG: 2 回に分けると cd が消える
cd /tmp/repos/claudelab.net
git pull --rebase origin main
 
# OK: 1 回にまとめる
cd /tmp/repos/claudelab.net && git pull --rebase origin main

たった一行のテクニックですが、これだけで全体の事故率が体感で 7 割以上減ります。Claude Code に「複数行のコマンドを書くときは 1 つの bash 呼び出しにまとめてください」と CLAUDE.md に書いておくと、自動生成時の事故も減らせます。

対処 2 — 絶対パスを徹底する

「cd を使わないで済むなら、最初から使わない」というのも有効な戦略です。私の場合、Dolice Labs のスケジュールタスクでは cd をほぼ使わず、すべて絶対パスで参照する方針に統一しました。

# NG: 暗黙の cwd に依存
cd content/articles/ja
ls
 
# OK: 絶対パス
ls /tmp/repos/claudelab.net/content/articles/ja

git -C <dir> <subcmd> も同じ思想で、cd なしで作業ディレクトリを指定できる便利な書き方です。

git -C /tmp/repos/claudelab.net pull --rebase origin main
git -C /tmp/repos/claudelab.net add content/
git -C /tmp/repos/claudelab.net commit -m "Add new article"
git -C /tmp/repos/claudelab.net push origin main

複数の bash 呼び出しに分かれても安全に動作します。

対処 3 — 環境変数はインラインで渡す

export で永続化したつもりの環境変数も、次の呼び出しでは消えます。一度きりしか使わない変数は、コマンドの直前にインラインで指定するのが安全です。

# NG
export GITHUB_TOKEN=ghp_xxxxxxxx
git clone https://${GITHUB_TOKEN}@github.com/foo/bar.git
 
# OK: 同じコマンドラインで完結させる
GITHUB_TOKEN=ghp_xxxxxxxx git clone https://${GITHUB_TOKEN}@github.com/foo/bar.git

ただし、トークン文字列を毎回ハードコードするとセキュリティ上望ましくないので、私のスケジュールタスクでは「ワークスペース内のファイルから読み出してインライン変数として使う」やり方で統一しています。

GITHUB_TOKEN=$(grep -A1 "^Claude Lab" "${WS}/_documents/_github_tokens/github_tokens.txt" | tail -1 | tr -d '[:space:]')
git clone --depth 1 "https://${GITHUB_TOKEN}@github.com/masakihirokawa/claudelab.net.git" /tmp/repos/claudelab.net

$WS のような複数回参照する変数も、必要な bash 呼び出しごとに WS=$(ls -d /sessions/*/mnt/Dolice\ Labs | head -1) を再評価する設計にしておくと混乱しません。

対処 4 — 永続的に持ち回りたい値は CLAUDE.md か一時ファイルに置く

毎回 cd や export を書くのが面倒な値(たとえばリポジトリのパスや GitHub PAT の場所)は、CLAUDE.md に「リポジトリは /tmp/repos/<site> を使う」「PAT は _documents/_github_tokens/ から読む」のように書いておくと、Claude Code が次回からそれを前提に bash を組み立ててくれます。

ファイル経由で値を渡したい場合は、/tmp の下にメモを書き出すのが現実的です。

# 1 回目: 状態を一時ファイルに保存
echo "/tmp/repos/claudelab.net" > /tmp/cc_workdir
echo "ghp_xxxxxxxx" > /tmp/cc_token
 
# 2 回目: 一時ファイルから読み戻す
WORK=$(cat /tmp/cc_workdir)
TOKEN=$(cat /tmp/cc_token)
git -C "$WORK" push "https://${TOKEN}@github.com/foo/bar.git" main

セキュリティ上、トークンを /tmp に書く場合は実行直後に削除してください(rm /tmp/cc_token)。

対処 5 — 複雑な処理はシェルスクリプトを書き出して実行する

cd と export が 3 つ以上絡むような処理は、無理に 1 行に詰め込まず、シェルスクリプトとしてファイルに書き出してしまうのが結果的に楽です。

cat << 'EOF' > /tmp/deploy.sh
#!/bin/bash
set -euo pipefail
WORK=/tmp/repos/claudelab.net
TOKEN=$(cat /tmp/cc_token)
cd "$WORK"
git pull --rebase origin main
# 何らかの長い処理
git add content/
git commit -m "Daily content update"
git push "https://${TOKEN}@github.com/masakihirokawa/claudelab.net.git" main
EOF
chmod +x /tmp/deploy.sh
 
# 別の bash 呼び出しから実行
bash /tmp/deploy.sh

set -euo pipefail を入れておくと、途中でコケた場合に黙って先に進むことがないので、デバッグも楽になります。スクリプトファイルにしておくと、人間が手元のターミナルで同じものを再現できるという副次的なメリットもあります。

同じ仕組みのツール — PowerShell ツール・サブエージェント

ここまで Bash ツールを例に書いてきましたが、同じ「呼び出しごとにステートを破棄する」仕様は、Claude Code の関連ツールにも共通しています。

PowerShell ツールも 1 回ごとに独立したセッションです。Set-Location で移動しても次の呼び出しでは元に戻ります。Cowork mode の mcp__workspace__bash も同じです。サブエージェント(Task ツール)も、呼び出し元のコンテキストや変数は引き継ぎません。

つまり、Claude Code のエコシステム全体が「ステートレスな実行ユニット」を前提に組まれていると考えてよく、これに合わせて自分のスクリプト設計を整えていくのが正解です。

設計のコツ — 「ステートレス前提」で書く

私が Dolice Labs の 4 サイト分の自動投稿パイプラインを整理し直したとき(2014 年から個人開発を続けてきた経験から言うと)、最終的に落ち着いたのは次の 3 原則です。

  1. どの bash 呼び出しも、それ単体で再実行できる形にする。途中だけ流して動作確認するときに楽です。
  2. 状態は変数ではなくファイルかパス引数で渡す。/tmp のメモか、絶対パスで完結させます。
  3. cd を書く場面は && か git -C のどちらかに置き換える。長期で見るとこれが一番事故が少ない方針でした。

Cowork mode のスケジュールタスクで毎日 4 本 × 4 サイト分の記事を自動投稿していますが、上の 3 原則に切り替えてから「cd が効かない系」のエラーは記録上ほぼゼロになりました。1997 年からインターネットとプログラミングに触れ続けてきた身としても、「呼び出しごとに状態を破棄する」というモデルは新鮮で、これに慣れること自体が AI エージェント時代のシェル運用のリテラシーだと感じています。

同じ症状で詰まっている方の参考になれば幸いです。次に Claude Code に複数ステップの bash を任せるときは、まず「これは && で 1 行にできないか?」を最初に自問する癖をつけてみてください。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

⟐ Claude Code2026-10-13
「cd して git add して commit」の承認が毎回出る — 設定の抜けではなく、仕様だと分かるまでにたどった道
cd /path && git add && git commit のような複合コマンドで、許可ルールを入れても承認が繰り返し出る。公式の権限ドキュメントと GitHub の報告を突き合わせると、cd と git の組み合わせは設計上プロンプトが出ると分かりました。原因の切り分け順と、手数を減らす4つの直し方を並べます。
⟐ Claude Code2026-09-01
heredoc のクォートを1つ落とすと、ログに書いた金額や日付が別物になります
未クォートの heredoc は本文の変数とバックティックを実行します。実測した4通りの書き換わり方、3種類のクォート記法の比較、プレースホルダと sed で値を安全に埋める手順、既存スクリプトを棚卸しする検出コードまでをまとめました。
⟐ Claude Code2026-08-25
settings.json のキー名を1文字間違えても、Claude Code は何も言わずに無視します
キー名を書き間違えた settings.json と正しい settings.json で claude doctor の出力を比べたところ、差分はゼロでした。何が検証され何が素通りするかを5通りで測り、書き間違いを自分で落とす検査を用意します。