Claude Codeでzoxideなどシェル関数が使えない原因と対処法
zoxideの__zoxide_z関数などがClaude CodeのBashツールで見つからない原因と、修正されたバージョン、PowerShellツールとの違いをまとめます。
Claude CodeのBashツールでzoxideのzコマンドを使うと、command not found: __zoxide_zのようなエラーで失敗することがあります。原因はzoxide側の不具合ではなく、Bashツールがシェル関数をセッション開始時に一度だけ捕捉する仕組みと、アンダースコアで始まる関数名を取りこぼしていた過去のバグにありました。症状の再現条件と、どのバージョンから解消しているかをまとめます。
通常のターミナルでは動くのにBashツールで失敗する
この問題は2025年6月21日、Claude Code v1.0.18を使うユーザーがGitHubに報告しました。環境はWSL2上のUbuntu、シェルはzsh、zoxideは0.9.8です。~/.zshrcにeval "$(zoxide init zsh)"を書いておくと、報告者の環境では通常のターミナルでcdが問題なく動いていました。標準の初期化が定義するのはzで、cdもzoxide経由にするには--cmd cdが要ります。この初期化コードはシェル関数__zoxide_zを動的に生成する仕組みです。
ところがClaude CodeのBashツールで同じcdを実行すると、z:1: command not found: __zoxide_zというエラーになりました。通常シェルではtype __zoxide_zが関数の実体を返すのに対し、Bashツール内では同じコマンドが「見つからない」と返します。報告者は手動での関数再定義、.zshrcの再読み込み、evalの直接実行、補完キャッシュのクリア、初期化オプションの変更を試しましたが、いずれも解決しませんでした。
同じ症状は複数のユーザーから寄せられています。fishシェルとdirenvの組み合わせで似た問題を報告したコメントもあり、そのユーザーはfish -i -cを前置きして実行する形で環境を読み込ませていました。当時のユーザーが試した回避策は次の3つです。
SHELL=/bin/bash claudeでzshではなくbashを使わせるclaudeコマンドをSHELL=/bin/bash付きでラップする関数を.zshrcに定義する- zoxideの初期化を対話シェルに限定するガード(
[[ $- == *i* ]] && eval "$(zoxide init --cmd cd zsh)")を追加する
2025年10月には、別のユーザーがプライベート関数だけが継承されていないようだと書き、zoxide initの出力から__プレフィックスをsedで除去する回避策を報告しました。この観察は、後述する修正内容と合っています。issueは2025年12月7日にボットが「30日間動きがない」と通知し、2026年1月10日にボットが「60日間動きがない」として自動クローズ、1月17日にロックされています。
報告のBusiness Impact欄は、影響がzoxideだけにとどまらないとも指摘しています。シェル関数に依存する開発生産性ツール全般が、同じ理由で動かなくなるという内容です。
Bashツールがシェル関数を取り込む流れ
公式ツールリファレンスによると、Bashツールは各コマンドの前にシェル設定を読み直しているわけではありません。取り込みはセッション開始時の1回で終わります。
シェル関数が各コマンドに届くまで
- 1
セッション開始時に設定ファイルを読む
使用中のシェルに応じて、
~/.zshrc・~/.bashrc・~/.profileのいずれかをソースします。 - 2
結果を捕捉する
ソースした結果として生まれたエイリアス・関数・シェルオプションを捕捉します。
- 3
以降のBashコマンドすべてに適用する
捕捉した内容が、セッション中に実行するすべてのBashコマンドへ適用されます。
どのシェルで実行するかはCLAUDE_CODE_SHELLで指定できます。値はbashかzshの実行ファイルのパスで、fishなど他のシェルには対応していません。パスが無効な場合は無視されて自動検出に戻り、自動検出は$SHELLがbashかzshならそれを使います。回避策だったSHELL=/bin/bash claudeは、この環境変数を使えば次のように書けます。
CLAUDE_CODE_SHELL=/bin/bash claudefishをログインシェルにしている場合も、Bashツールの中身はbashかzshになります。捕捉の対象は.zshrc・.bashrc・.profileなので、config.fishに書いた関数は含まれません。
引き継がれるものと引き継がれないもの
シェル関数と環境変数は、同じBashツールの中でも扱いが逆になります。
Bashツールで持ち越されるもの
関数・エイリアス
セッション開始時に1回捕捉され、以降のすべてのコマンドで使えます。zoxideの__zoxide_zはこちらです。
exportした環境変数
各コマンドは別々のプロセスで走るため、前のコマンドでexportした値は次のコマンドに届きません。仮想環境はClaude Codeの起動前に有効化します。
作業ディレクトリのcdは、プロジェクトディレクトリ内であれば持ち越されます。サブエージェントのセッションでは持ち越されません。毎回プロジェクトのディレクトリから始めたい場合は、CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR=1を設定します。Linux/WSLでコマンドのメモリ使用量に上限をかけるCLAUDE_CODE_TOOL_MEMORY_LIMITのように、Bashツールにはドキュメント化された個別の挙動がいくつかあります。
Bashツールという呼び方自体も、コード実行系のほかの仕組みと混同されがちです。この点はcode executionとbashツールの混同が起きる実行環境の対処法で扱っています。
アンダースコアで始まる関数名が消えていた
公式changelogを遡ると、関数の捕捉処理そのものに、アンダースコアで始まる関数名を取りこぼすバグがあったことが分かります。
| バージョン | 公開日 | 修正内容 |
|---|---|---|
| v2.1.47 | 公開日2026年2月18日 | 修正内容ダブルアンダースコアで始まる関数(__git_ps1など)がシェルセッション間で保持されない不具合を修正 |
| v2.1.147 | 公開日2026年5月21日 | 修正内容シェルスナップショットがシングルアンダースコアで始まるユーザー関数を落とし、それを参照するエイリアスが壊れる不具合を修正 |
zoxideの__zoxide_zもダブルアンダースコアで始まるので、v2.1.47の修正が当てはまると考えられます。changelogが参照しているのはissue #25824で、zoxideでの再検証は載っていません。タイトルは「Shell snapshot drops __-prefixed functions, breaking cd when used with mise」です。mise(バージョン管理ツール)のactivateが定義する__zsh_like_cdが捕捉から落ち、cdのたびにcommand not foundになる報告でした。このissueは2026年2月14日に立ち、2月16日にクローズされ、2月18日公開のv2.1.47で修正されています。
zoxideのissue #2407は修正されないまま自動クローズされましたが、同じ「__始まりの関数が落ちる」原因は別のissueで扱われ、修正されています。放置クローズされたissueだからといって、問題が直らないまま残るとは限りません。
直らないときの切り分け
v2.1.47以降でも症状が出る場合は、次の3点を順に確かめます。
動かないときの3つの確認先
バージョン
claude --versionで実際のバージョンを確認し、アップデートはclaude updateで行います。v2.1.47未満では__始まり、v2.1.147未満では_始まりの関数が影響を受けます。なおv2.1.147は一部の環境でBashツールが全コマンドでexit code 127を返す回帰があり、v2.1.148で修正されました。実際に使われているシェル
ログインシェルをzshに変えたつもりでも、ターミナルアプリやOS側の設定が古く、bashが使われていることがあります。
echo $SHELLやps -p $$で確かめ、必要ならCLAUDE_CODE_SHELLで指定します。設定を書いたタイミング
.zshrcを編集したのが現在のセッションの開始後なら、まだ捕捉されていません。claudeを起動し直します。
fishやnushellのように、bashとzsh以外で関数を定義している場合はCLAUDE_CODE_SHELLの対象外です。同じ関数をbashかzshの設定ファイルにも書く形になります。
現在のバージョンでzoxideを使う設定
__始まりの関数の取りこぼしはv2.1.47で、シングルアンダースコア関数の取りこぼしはv2.1.147で、それぞれ修正されています。それ以降のバージョンでは、ガードなしの標準的な初期化(zoxideのREADMEにあるeval "$(zoxide init zsh)")で動くと考えられます。
# ~/.zshrc に1行追加
eval "$(zoxide init zsh)".bashrcを使っている場合はzoxide init bashに置き換えます。設定を追加した直後は、Claude Codeのセッションを再起動して反映させます。個別のBashコマンドを検査・制御したい場合は、PreToolUse hookを組み合わせる選択肢もあります。
nvmのようにPATHを書き換えるだけのツールは扱いが別
zoxideは関数を生成するツールですが、nvmのようにPATHなどの環境変数だけを書き換えるツールは扱いが異なります。環境変数は自動では捕捉されないため、CLAUDE_ENV_FILEにexport文を書くか、SessionStart hookで動的に生成します。CLAUDE_ENV_FILEは、各Bashコマンドの前に同じシェルプロセスで実行されるスクリプトのパスです。公式ドキュメントは、セットアップコマンドの前後で環境変数を比較し、差分だけを書き出す方法を示しています。
#!/bin/bash
ENV_BEFORE=$(export -p | sort)
source ~/.nvm/nvm.sh
nvm use 20
if [ -n "$CLAUDE_ENV_FILE" ]; then
ENV_AFTER=$(export -p | sort)
comm -13 <(echo "$ENV_BEFORE") <(echo "$ENV_AFTER") >> "$CLAUDE_ENV_FILE"
fi
exit 0CLAUDE_ENV_FILEをhookから動的に埋められるのは、SessionStart・Setup・CwdChanged・FileChangedの4種類です。シェル関数の捕捉とこの仕組みは独立しているため、両方を必要とするツールチェーンでは組み合わせて使うことになります。
PowerShellツールではプロファイルが読み込まれない
同じシェル関数の話でも、WindowsのPowerShellツールでは事情が異なります。公式ドキュメントはプレビュー中の既知の制限として「PowerShellプロファイルは読み込まれない」ことを挙げています。つまり$PROFILEに定義した関数は、Bashツールの.zshrcのようには捕捉されません。
zoxide init powershellが生成する関数をプロファイル経由で使っている場合、Bashツール側の修正とは独立に、この制限がそのまま当てはまります。
使い方別の現状
| 使い方 | 現状 |
|---|---|
| zsh/bashでzoxideなどダブルアンダースコアの関数を使う | 現状v2.1.47以降で修正対象(zoxideでの再検証は未掲載) |
| zsh/bashでシングルアンダースコアで始まる関数・エイリアスを使う | 現状v2.1.147以降で解消 |
| fishなどbash・zsh以外で定義した関数を使う | 現状CLAUDE_CODE_SHELLの対象外 |
| PowerShellツールでプロファイル前提の関数を使う | 現状プレビュー中の制限が残る |
| コマンド間で環境変数だけを共有したい | 現状関数の捕捉とは別にCLAUDE_ENV_FILEかhookが必要 |
まとめ
__zoxide_zが見つからない症状は、アンダースコア始まりの関数名を捕捉処理が落としていたことが原因と考えられ、v2.1.47(__始まり)とv2.1.147(_始まり)で修正されています。今も出るなら、バージョン、実際に使われているシェル、設定を書いたタイミングの順に確かめると原因を絞れます。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。