bat でファイルを開くと、中身は出るのにプロンプトが返ってきません。zi は移動だけして無言で固まる。どちらも Ctrl-C では抜けられます。
同じ実行ファイルを直接叩くと、両方とも普通に動きました。
shim はプロセス 3 個
mise\shims\bat.exe は bat ではありません。mise を起動し、mise がこのディレクトリで使うべき bat を解決し、それを起動する。そういう小さなプログラムです。コマンド 1 つにプロセス生成が 3 回。
このマシンはウイルス対策が集中管理されていて、プロセスを作るたびに検査が入ります。bat --version を 15 回ずつ:
| 経路 | |
|---|---|
| shim | 127 ms (115–144) |
| 実行ファイルへの symlink | 15 ms (11–28) |
ツール本体は 15 ms。残りの 112 ms は、増えた 2 プロセス分の検査です。
遅いだけならプロンプトは返ってくる
shim は、起動したツールが終わるまで自分も終了しません。端末とツールの間に、コンソールプロセスがもう 1 つ挟まった状態が最後まで続きます。
止まった 2 つは、どちらも端末そのものを使うコマンドでした。bat は画面をless に渡し、zi は移動先を標準出力へ書いてシェルに読ませます。相手が端末である前提で書かれているところに、shim が 1 枚入っていたわけです。
mise activate を選ばなかった理由
mise activate は解決をシェル側に移します。プロンプトのたびにフックが走り、今いるディレクトリで見えるべきツールへ PATH を書き換える。これなら間に何も挟まりません。
ただし、そのフック mise hook-env 自体がプロセス 1 個です。同じ検査を受けて 130 ms。次に打つのが mise のツールでなくても、プロンプトを出すたびに 130 ms 払います。PATH も 7,265 文字まで伸びる。上限は 8,191 で、残り 894 文字の使い道はPATH の予算のほうにあります。
farm
%LocalAppData%\mise\bin に、実行ファイルを指す symlink をツールごとに 1 本置いています。プロセス 1 個、PATH エントリ 43 文字 1 本、フック無し。
windows/Sync-MiseBinFarm.ps1 が shims ディレクトリから組み立てます。shim
204 本のうち、リンクを張るのは 144 本:
- 名前で除外、44 本。 python と pip は標準ライブラリを自分の実行ファイルからの相対で探すので、symlink 経由だと farm の中を探しにいって空振りします。
rust 系は
~/.cargo/binから既に届くため対象外。 - リンク先が PE ファイルでない、10 本。
.cmdを指すnpm.exeはローダーが弾きます。残る 8 本は拡張子そのものが無く、名前を見ても判別できません。 - mise がもう解決しない、6 本。
この 60 本は shim のまま動きます。遅いだけで、壊れてはいません。
リンクが切れたとき
symlink はパスを 1 本だけ名指しします。mise up でインストール先がtools/node/22.14.0 から 22.15.0 へ動けば、リンクはそこで切れる。farm はこの構成で唯一、定期的な手入れが要る部分です。
- シェルを開くたびに、PowerShell のプロファイルが同期を走らせます。
- リンク先の消えた本数は
windows/doctor.ps1が数えて出します。 windows/path-order.tomlが farm を shims より前に固定しています。リンクの無いツールは 127 ms の経路へ落ちるだけで、実行はできます。