Claude Media
Claude Codeのalias hashでクリップボードが空になる原因と回避

Claude Codeのalias hashでクリップボードが空になる原因と回避

zshでhashという名前のaliasを持つと、Claude CodeのBash呼び出しのたびにそのaliasが走ります。pbcopy入りならクリップボードが空になる仕組みと、確かめ方、dotfiles側の回避をまとめます。

zshでhashという名前のaliasを定義していると、Claude CodeのBashツールを呼ぶたびにそのaliasが実行されます。aliasの中身がpbcopyなら、コマンドを走らせるたびにmacOSのクリップボードが空に上書きされます。

原因は、Claude Codeがシェルの状態を保存したスナップショットの中のhash rgという確認行です。この行をzshがaliasとして展開してしまいます。GitHubのissue #101498で報告されており、状態はopenです。

症状はどんな形で出るか

issueの報告者は、4つのセッションを同時に開いた状態で、アプリを問わずクリップボードが数秒おきに空になったと書いています。コピーした直後に貼り付けても何も出ない、という形で気づく症状です。

報告者のhashaliasは、あるコマンドの出力をawkで加工し、最後にpbcopyへ渡すものでした。hash rgとして呼ばれたときは出力が空になり、pbcopyが0バイトを書き込みます。macOSの統合ログ(process == "pboard")にも、0バイトを書く短命なpbcopyプロセスが残っていたとのことです。

クリップボードが空になるのは、この報告者のaliasがpbcopyを含んでいたからです。issueには「バグはpbcopyに限らない。hashという名前のaliasは、副作用ごとBashツールの呼び出しのたびに走る」とあります。ログ追記、通知、ネットワーク送信を含むaliasでも、同じ頻度で動く理屈です。

なぜhashが実行されるのか

Bashツールは、セッションの開始時にシェルの設定ファイルを読み込みます。仕様では、~/.zshrc・~/.bashrc・~/.profileのうちシェルに応じたものを読み、できあがったaliasとシェル関数とシェルオプションを取り込み、以後のすべてのBashコマンドに適用します。使うシェルをzsh以外に変える場合の考え方はClaude CodeでNushellは使えるかにあります。

この取り込み先が、~/.claude/shell-snapshots/に作られるスナップショットのファイルです。issueの抜粋では、zsh用のスナップショットに次の2種類の行が並んでいます。

手順

スナップショット内で起きていること

  1. 1

    aliasの復元

    ユーザーのaliasがalias -- hash=...の形で書き込まれます。issueの例では4602行目です。

  2. 2

    ripgrepの有無の確認

    その後ろの4626行目で、if ! hash rg 2>/dev/null && ! typeset -f rg >/dev/null 2>&1; thenが実行されます。

  3. 3

    aliasの展開

    zshはsourceされたファイルの中でもaliasを展開します。hashがaliasなら、組み込みのhashではなくユーザーのaliasがrgを引数にして走ります。

この確認はBashツールの呼び出しのたびに通るため、aliasも毎回走ります。issueには、実行中のプロセスツリーも載っています。claudeの下で/bin/zsh -c source ~/.claude/shell-snapshots/snapshot-zsh-<id>.sh ...が動き、その子としてalias側のコマンドがrg付きで起動していました。

手元で再現して確かめる

issueの再現手順は、副作用を持たない最小のaliasです。~/.zshrcに次の1行を足します。

alias hash='echo "hash alias ran" >> /tmp/hash-alias.log; builtin hash'

新しいClaude Codeセッションを起動し、Bashでlsのような適当なコマンドを何回か走らせてから、ログを数えます。

wc -l /tmp/hash-alias.log

行数がBashツールの呼び出し回数と同じだけ増えていれば、同じ現象です。issueではこの手順で呼び出し1回につき1行が追記されると報告されています。なお、報告者自身が注記しているとおり、この最小のaliasは元のaliasの代役で、新規セッションではなくスナップショットの2行をzshで試して確かめたものです。元のaliasが動く様子は実際のセッションで見ています。

自分の環境でaliasが取り込まれているかは、次の2つで切り分けられます。

# スナップショットにhashのaliasが入っているか
grep -n 'alias -- hash=' ~/.claude/shell-snapshots/snapshot-zsh-*.sh
 
# 通常のzshでhashが何に解決されるか
zsh -ic 'whence -v hash'

1つ目に行が出れば、スナップショットを経由してaliasが毎回走る条件が揃っています。2つ目がhash is an alias for ...と返す場合も、元になるaliasが.zshrc側にあります。

隣のtypesetの確認も同じ理屈で走るので、typesetのaliasも同様に探せます。

grep -n 'alias -- typeset=' ~/.claude/shell-snapshots/snapshot-zsh-*.sh

zsh 5.9で断片を再現した結果

私の手元のzsh 5.9で、スナップショットの2行を模した小さなファイルをsourceしました。aliasは副作用としてログに1行書くだけの、課題の再現用です。

alias hash='echo "hash alias ran" >> $LOGF; builtin hash'
if ! hash rg 2>/dev/null && ! typeset -f rg >/dev/null 2>&1; then echo fallback-a; fi
if ! \builtin hash rg 2>/dev/null && ! \builtin typeset -f rg >/dev/null 2>&1; then echo fallback-b; fi

ログに1行だけ記録されました。1行目のhash rgでaliasが動き、\builtinを付けた2行目ではaliasが走っていません。これは断片の挙動の確認で、Claude Code本体を起動した結果ではありません。

issueが提案している直し方

issueの「What Should Happen?」は、Claude Codeがスナップショットに足す行はユーザーのaliasを実行しないようにする、という内容です。例としてbuiltin hash rgとcommand -v rgが挙がっています。もう1つの案は、aliasを復元する前に確認を済ませることです。

コメント欄には、別の人が/bin/zsh -df(zsh 5.9)で独立に確かめた結果があります。要点は次のとおりです。

  • hashのaliasは、rgが実行ファイルでも、シェル関数でも、存在しなくても呼ばれる
  • 続くtypeset -f rgの確認も、typesetにaliasがあれば呼ばれる
  • rgの3状態と、hash・typesetそれぞれのalias、両方のaliasを組み合わせた5ケースでは、組み込みを明示した場合にどちらのaliasも呼ばれなかった
  • 候補の書き方はif ! \builtin hash rg 2>/dev/null && ! \builtin typeset -f rg >/dev/null 2>&1; then。先頭のバックスラッシュで、builtinそのもののaliasも展開されない
  • hashだけ直すと隣のtypesetの確認が残るため、両方を直す。ほかのスナップショット生成行にも同じ見直しが要る

このコメントが確かめたのは引用した断片であり、新しいセッションでの動作や報告者のクリップボードの事象ではない、と本人が断っています。スナップショットを作る実装は公開リポジトリに見当たらないため、修正はClaude Code側のチームが生成時に入れ、回帰テストする必要がある、という結びです。

いつから起きたのか

報告者は、不具合に気づいたのを2026-10-05ごろとしています。aliasは2026年2月からあり、クリップボードの問題だけが最近出始めた、という経緯です。

changelogでは、2026-10-05付けのバージョン2.1.290に「Bashツールが、新しい設定ディレクトリで起動直後の最初のコマンドを数秒以内に実行すると、セッション全体でシェルのaliasや関数、プラグインのPATH項目を失うことがあるのを修正」という項目があります。報告者はこの変更との関係を確認していないと明記しています。関係は未確認です。

issueが報告している環境はClaude Code 2.1.296、macOS、zshです。回帰かどうかの質問には「はい」と答えていますが、最後に問題がなかったバージョンは不明とされています。issueのラベルはbug・has repro・platform:macos・area:bashです。bashのスナップショットで同じ現象が起きるかは、issueの本文に記載がありません。

修正が入るまでのdotfiles側の回避

Bashツールが固まる別の原因として、macOSでHomebrewのbashを使っている場合はheredocが固まる原因があります。こちらはaliasとは無関係なので、症状が違えば切り分けてください。Bashツールのコマンドをラッパー経由にする変数はCLAUDE_CODE_SHELL_PREFIXの解説で扱っています。

Claude Code側の修正を待つ間、手元でできることは、aliasの扱いを変えることに尽きます。以下はissueに書かれた公式の回避策ではなく、原因から導ける選択肢です。

方法内容注意点
aliasの改名内容hashを別の名前に変える注意点一番確実。以後Bashツールの確認行には影響しない
読み込み条件の追加内容.zshrcで、Claude Codeのサブプロセスでは定義しない注意点後述の確認が要る

改名は、.zshrcのaliasの名前を書き換えるだけです。

# 変更前
alias hash='...'
# 変更後(名前は任意)
alias hsh='...'

2つ目は、CLAUDECODE環境変数を使う案です。仕様では、CLAUDECODEはBashツールなどClaude Codeが起動するサブプロセスで1になります。.zshrcの中で[[ -z $CLAUDECODE ]]のときだけaliasを定義すれば、理屈の上では避けられます。

if [[ -z $CLAUDECODE ]]; then
  alias hash='...'
fi

ただしスナップショットを作るためのシェルにこの変数が付くかどうかは、公開されているドキュメントに書かれていません。試すときは、先ほどのgrepでスナップショットにaliasの行が残っていないことを確かめてから使います。

名前がhashである必要がなければ、改名が最短です。hashは本来、コマンドのパスのキャッシュを扱う組み込みコマンドなので、別の用途で上書きしていること自体が、ほかのスクリプトでも思わぬ副作用の元になります。

まとめ

hashという名前のaliasは、Claude Codeのスナップショットのhash rg確認で毎回走ります。副作用を持つaliasなら、その副作用もBashツールの呼び出しごとに起きます。grepでスナップショットを確かめ、当てはまるなら改名するのが最短の対処です。

issueはopenで、修正の予定やバージョンは示されていません。更新が入ったかは、issue #101498とchangelogで確かめられます。

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