Skip to content

[Bug][Windows] Shell 快照写入了 Windows 格式 PATH,Git Bash 下 ls/rm 等外部命令全部 command not found (exit 127) #5

Description

@zhangbaobao36

问题描述

在 Windows 11 + Git for Windows (Git Bash) 环境下,Bash 工具执行的所有外部命令都报 command not found (exit 127)——lsrmhead,连 powershell.exe 也不行;只有 bash 内置命令(echofor 等)能正常工作。

根因分析

src/utils/bash/shell_snapshot.rsget_claude_code_snapshot_content()

let path = env.var("PATH").unwrap_or_default();      // ← Rust 进程的 PATH,Windows 格式
content.push_str(&format!(
    "      echo \"export PATH={}\" >> \"$SNAPSHOT_FILE\"\n",
    crate::utils::bash::shell_quote::quote(&[&path])
));
  • MSYS2 运行时只在 bash 进程启动瞬间把 PATH 环境变量自动转换成 Unix 格式(/usr/bin:/c/...);
  • Rust 侧读到的是转换前的 Windows 格式 PATH(D:\...;C:\...),被原样写进快照文件;
  • 运行中的 bash 里对字符串变量赋值不会再触发 MSYS 转换,于是 bash 的 PATH 变成一整个畸形目录,所有依赖 PATH 的外部命令全部 127。

对比同一台机器上官方 Claude Code 生成的快照(它写 export PATH=$PATH,由 login shell 内部展开,拿到的已是 MSYS 格式):

# cometix 生成的快照(异常)
export PATH='D:\Anaconda3\condabin;C:\Users\...'

# 官方 Claude Code 生成的快照(正常)
export PATH=/mingw64/bin:/usr/local/bin:/usr/bin:/bin:/c/Users/...

最小复现(不依赖本工具,纯 bash)

# 写死 Windows 格式 PATH(等价于当前实现的副作用)
bash -c "export PATH='D:\\Git\\usr\\bin;C:\\Windows\\System32'; ls --version | head -1"
# → head: command not found

# bash 内部展开 $PATH(官方 CC 的语义)
bash -c 'export PATH=$PATH; ls --version | head -1'
# → ls (GNU coreutils) 8.32

这个差异在 macOS/Linux 上不存在—‼进程 PATH 与 bash 内 PATH 本就同值,两种写法结果完全相同,所以纯 mac 开发环境下很难被发现。

修复建议

--- a/src/utils/bash/shell_snapshot.rs
+++ b/src/utils/bash/shell_snapshot.rs
@@ -150,7 +150,7 @@
-fn get_claude_code_snapshot_content(env: &crate::utils::process_env::EnvSnapshot) -> String {
+fn get_claude_code_snapshot_content(_env: &crate::utils::process_env::EnvSnapshot) -> String {
@@ -171,11 +171,11 @@
-    let path = env.var("PATH").unwrap_or_default();
-    content.push_str(&format!(
-        "      echo \"export PATH={}\" >> \"$SNAPSHOT_FILE\"\n",
-        crate::utils::bash::shell_quote::quote(&[&path])
-    ));
+    // Windows fix: capture PATH from inside the login bash ($PATH there is
+    // MSYS-normalized). Embedding the raw Windows-format process PATH made
+    // every external command in snapshot sessions fail with exit 127.
+    content.push_str("      echo \"export PATH=$PATH\" >> \"$SNAPSHOT_FILE\"\n");

_env 改名是因为该参数此后不再被使用,避免 unused 警告。)

环境

  • OS: Windows 11 (x64)
  • Git: 2.52.0.windows.1(完整版 Git Bash)
  • 版本: 0.2.0(master 源码本地编译,基线 d7f123e

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions