{"id":"51dea574-85f6-49f7-ac37-1a088787ef70","entityType":"agent","slug":"clawhub-chenmo0414-windows-shell","name":"windows-shell","canonicalUrl":"https://www.xpersona.co/agent/clawhub-chenmo0414-windows-shell","canonicalPath":"/agent/clawhub-chenmo0414-windows-shell","generatedAt":"2026-10-11T14:13:02.144Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T11:29:54.514Z","emptyReason":null},"description":"Windows 命令行工作规范：先选对 shell（默认 Git Bash），再避开编码与 MSYS2 参数改写两类陷阱。覆盖 GBK/UTF-8、BOM、MSYS2 路径转换、PowerShell/pwsh、WSL 判定、Python/Node.js、Git 配置与代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。细节按需读 references/。 Skill: windows-shell Owner: chenmo0414 Summary: Windows 命令行工作规范：先选对 shell（默认 Git Bash），再避开编码与 MSYS2 参数改写两类陷阱。覆盖 GBK/UTF-8、BOM、MSYS2 路径转换、PowerShell/pwsh、WSL 判定、Python/Node.js、Git 配置与代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。细节按需读 references/。 Tags: latest:5.3.0 Version history: v5.3.0 | 2026-08-20T10:52:34.177Z | user 补两条，否掉一条。候选来自 agent 实测自报的「规范没写、只能靠自有知识现推」， 再用 TokenHub 多模型探针筛出其中模型真不会的（每格 5 次采样，共 240 次调","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.1K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s171zews55hjbzfkyz1vv4mg05846nxs:windows-shell","sourceUrl":"https://clawhub.ai/chenmo0414/windows-shell","homepage":"https://clawhub.ai/chenmo0414/skills/windows-shell","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/chenmo0414/windows-shell","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/chenmo0414/skills/windows-shell","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":61,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Windows 命令行工作规范：先选对 shell（默认 Git Bash），再避开编码与 MSYS2 参数改写两类陷阱。覆盖 GBK/UTF-8、BOM、MSYS2 路径转换、PowerShell/pwsh、WSL 判定、Python/Node.js、Git 配置与代码生成规则。适用于 Windows 10/11 +"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T11:29:54.514Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T11:29:54.514Z","emptyReason":null},"stars":null,"forks":null,"downloads":1076,"packageName":null,"latestVersion":"5.3.0","tractionLabel":"1.1K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T11:29:54.443Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T11:29:54.514Z","lastCrawledAt":"2026-10-11T11:29:54.443Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T11:29:54.443Z","lastVerifiedAt":null,"highlights":[{"version":"5.3.0","createdAt":"2026-08-20T10:52:34.177Z","changelog":"补两条，否掉一条。候选来自 agent 实测自报的「规范没写、只能靠自有知识现推」， 再用 TokenHub 多模型探针筛出其中模型真不会的（每格 5 次采样，共 240 次调用）。 **新增 1：`PIPESTATUS` 会被下一条命令重置，包括赋值语句本身。** cmd | tail -1; a=${PIPESTATUS[0]}; b=${PIPESTATUS[1]} # ✗ b 恒为 0 cmd | tail -1; st=(\"${PIPESTATUS[@]}\") # ✓ 紧邻、一次取完 实测 `(exit 7) | tail -1`：紧邻读得 7，中间隔一条命令再读得 0，先赋值再读第二个也得 0。 原规范只写了「用 ${PIPESTATUS[0]}」，没说它会失效——三个 agent 都在这上面栽过。 TokenHub 裸问命中率 40%，加规则后 deepseek 两个模型由 4/5、2/5 拉满到 5/5。 **新增 2（辟谣条目）：中文写在 `-Command '...'` 参数里是安全的，不需要 BOM。** powershell -NoProfile -Command '$s=\"中文测试\"; Write-Output $s.Length' # → 4，正确 要 BOM 的只有**脚本文件**（见 5.2.0），命令行参数走的是另一条路径。这条是反向陷阱： 实测中有两个 agent 因为担心参数被 ANSI 吃掉，绕道去写带 BOM 的 .ps1，白花两条命令。 TokenHub 裸问只有 40% 答对——六成情况下模型会误以为会坏。 **否掉：编码判定方法（`od` 看字节区分 GBK/UTF-8）。** 四个 agent 点名「规范没写这个」，但 TokenHub 三模型裸问 **15/15 全对**，两轮复测一致。 它们不是不知道，是不确定该不该做这一步。写进去纯属浪费篇幅，故不收。 这条同时给出一个方法学结论：**agent 自报的 spec_gaps 不能直接采信**。四条候选里， 一条被证伪（中文传 -Command 根本不会坏，是 agent 误判）、一条被证明模型早就会 （od 判编码）、只有两条真该写。全部采信会白白撑大主文件。 **一个需要警惕的信号**：主文件已达 8716 字节，逼近测试守卫的 9000 上限。该上限的依据 是实测的成本曲线（1.9KB 反弹到 1.01x、6.4KB 最优 0.87x、18KB 是 1.43x），现在已超出 验证过的最优区间。下次再加内容前应先重测成本，不要直接抬高守卫。 **已知局限**：minimax-m3 在 PIPESTATUS 这条上给了规范仍是 0/5，中文 -Command 那条也只 到 2/5。另两个模型均为 5/5，故判断为该模型在细节题上的固有弱项，未为其调整措辞。","fileCount":9,"zipByteSize":28486},{"version":"5.1.0","createdAt":"2026-08-19T16:05:30.011Z","changelog":"新增一条静默失败陷阱，来自一次「能不能砍得更狠」的对照实验。 **PS 5.1 读无 BOM 的 UTF-8 文件，不显式写 `-Encoding UTF8` 会静默算错行数。** 实测：一个 3 行的 UTF-8 文件，某行末尾字节为 `a1 8c 0a`，PS 按 GBK 把 `8c` 当作 双字节前导、吞掉紧随的换行，`Get-Content` 返回 **2 行**，而 `$?` 仍是 `True`。 这不是「可能乱码」那种显眼的错，是结果错但不报错——性质与规则 1 的参数改写完全相同。 原表格里虽有「UTF-8 → `-Encoding UTF8`」一行，但那是当作普通对照写的，读者会以为 不加只是可能乱码。现升格为显式警告，并在开头的判别表中增设**「静默失败」**一类： 没报错但结果就是不对（参数变了值、行数少一行）→ 必须交叉验证。 发现过程：为回答「规范还能不能更省」，做了一版 1.9KB 的极简规范（只保留实测中模型 真正做错的两条）做对照。结果是**砍过头会反弹**： | 规范 | 命令数 | 总 token（vs 无规范） | |------|------|------| | 无 | 19.2 | 1.00x | | 18 KB 全量 | 15.8 | 1.43x | | **6.4 KB 按需（本版基线）** | **11.2** | **0.87x** | | 1.9 KB 极简 | 17.5 | 1.01x | 砍掉 4.5KB 省下的阅读量，被多出来的 6.3 条试错命令吃光还倒亏。四个 agent 共列出 23 条「规范没写、只能靠自有知识补」的缺口——编码判定方法、venv/pytest 具体命令、 Python 转码写法各被点名 3–4 次。模型确实「会」，但每次现推都要花命令。 结论：**6.4KB 附近就是这套规范的成本最优点**，再砍会反弹。而极简版意外撞出的这条 静默失败，恰恰证明了「模型自己会」的那些条目不能省——g4 就是栽在被我砍掉的那一行上。","fileCount":9,"zipByteSize":24755},{"version":"5.0.0","createdAt":"2026-08-19T15:20:06.349Z","changelog":"结构性变更：改为**按需展开**，并把 `windows-shell-routing` 合并进来。 起因是一组 A/B 实测。四臂各跑 4 次同一个 Windows 任务（16 次运行），结论有两条： - **skill 的作用是精确的，不是普遍的。** 16 次里唯一 100% 分离的指标是「参数被静默改写」 这一步——无 skill 组 0/4 一次通过，读了规范的三组 12/12 全部一次通过。其余步骤靠常识 也能过，测不出差别。 - **篇幅不等于价值。** 只读 10KB routing 的一组，总 token 是无 skill 组的 1.09 倍； 只读 18KB windows-shell 的一组是 1.43 倍、耗时 1.31 倍——而两组在那个关键步骤上 效果完全相同。多出来的 8KB 没有兑现任何行为差异。 所以把一次性全量加载改成按需加载： - `SKILL.md` 缩到 138 行 / 5.8KB，只保留实测中真正拉开差距的内容：两类问题的判别、 shell 选型速查、五条高频规则、一次性环境配置，以及一张「遇到什么读哪个」的索引表。 - 细节移入 `references/`（25KB，5 个文件）：`encoding.md`、`msys2.md`、 `shell-routing.md`、`gitbash-pitfalls.md`、`wsl.md`。规则原文一字未改，只是换了位置。 - **默认加载量降到原来的 20%**（28.3KB → 5.8KB），完整信息量不减。 合并 `windows-shell-routing`：该技能的全部内容进入 `references/shell-routing.md`、 `wsl.md`、`gitbash-pitfalls.md`，选型速查表上浮到主文件第二节。之所以能合并，正是因为 有了按需加载——此前拒绝合并的理由是「两者相加 527 行太长」，那个理由现在不成立了。 原 slug 走 ClawHub 重定向。 测试相应增加渐进式披露的守卫：主文件体积上限、references 链接必须可解析、不得有孤儿 文件、以及七个「逃生开关」必须存在于 bundle 中的某处（它们是实测中真正改变了 agent 行为的部分）。 **发布前做了效果验证，并据此回填了两条。** 首版拆分后重跑同一任务，发现第 1 步 （GBK 遗留文件转码）的一次通过率从 4/4 掉到 1/4——四个 agent 都正确判出了 GBK，却有 三个先去试 `iconv`，撞上「Git Bash 没有 iconv」；那条提示被我移进了 references， 主文件只剩一个指针。同时有三个 agent 点名想查「PS 5.1 怎么写无 BOM 的 UTF-8」， 主文件只警告了陷阱、没给配方。 于是把这两条回填主文件（新增第 4 条「Git Bash 少几个你以为有的工具」，并在第 3 条 补上 `WriteAllText` + `UTF8Encoding($false)` 的写法），主文件从 5.8KB 到 6.4KB。 重跑验证：第 1 步回到 4/4，命令数 11.2（六臂最低），总 token 相对无规范 0.87x ——**是所有方案里唯一比不用规范还便宜的**。相对拆分前的 18KB 全量版： token 0.60x、耗时 0.54x、命令 0.71x。 跨模型交叉验证（经腾讯 TokenHub 调 deepseek-v3.2 / v4-flash / v4-pro / kimi-k3 / minimax-m3 五个模型，各 6 道知识探针）：回填后「Git Bash 有无 iconv」一题从 1/5 修正到 5/5。另有一条稳定的发现——`MSYS_NO_PATHCONV` 这个解法，五个模型两轮共 10 次 裸问**没有一次答对**，而给了规范后 5/5 全对。模型知道参数会被改写，却不知道怎么解决； 这正是本技能存在的意义所在。 **一个诚实的限制**：两轮共 8 次运行中，agent 读取 references 的次数是 **0**， 全部自评「主文件够用」。所以当前成立的其实是「主文件压缩到够用 + 附录供人查阅」， 而不是 agent 会自己按指针去取。今后往 references 放内容需按此前提判断： 凡是 agent 真正需要的，必须留在主文件里。","fileCount":9,"zipByteSize":23440},{"version":"4.4.0","createdAt":"2026-08-19T07:49:05.865Z","changelog":"新增 MSYS2 参数改写规则，并修正三处经复测证伪的旧结论。稳定性结论均为 12 次采样， 不再是单次观察。 修正： - **pwsh 7 不再标注「输出可能乱码（实测不稳定）」**。实测 12/12 稳定 UTF-8。 UTF-8 前缀只对 PS 5.1 必需；外部程序（node/python）的输出穿过 PowerShell 不会被改， 两侧都不受影响。规则 1 改为一张按「中文来源 × 是否加前缀」划分的实测表。 - **`reg query` 移出编码禁用表**。它的失败是 MSYS2 把注册表路径当 Unix 路径改写 （报「无效语法」而非乱码），加 `MSYS_NO_PATHCONV=1` 后原命令即可正常工作，与编码无关。 规则 3 因此拆为 A 类（真编码问题：wmic/systeminfo/ipconfig/netstat/tasklist/net user） 与 B 类（参数改写：reg query/findstr/schtasks），两类解法完全不同。 - **规则 4 补上前提**。配好用户级 `PYTHONUTF8` 后裸 `python -c` 已经正常； `-X utf8` 的价值在于不依赖环境（CI、容器、别人的机器），而非「不加必乱码」。 附反证：清空该变量后 `getpreferredencoding` 立刻退回 `cp936`。 新增（原规则 6/7/8 顺延为 8/9/10）： - **规则 6：MSYS2 会改写以 `/` 开头的参数**。`/api/v1/users` 被改写成 `D:/Program Files/Git/api/v1/users`，`/S /C` 变成 `S:/ C:/`，Docker 的 `-v` 参数被吃掉。 最坏的是它**静默生效**——不报错、退出码正常、参数已经变了。给出 `MSYS_NO_PATHCONV` / `MSYS2_ARG_CONV_EXCL` / 双斜杠三种解法，并说明为什么不能全局导出 （会让 `/c/Users/...` 这类本该转换的参数也不转）。 - **规则 7：`ln -s` 默认产出普通文件副本**，影响 pnpm workspace / npm link； `MSYS=winsymlinks:nativestrict` 可修，附开发者模式检查命令。 另新增开头的「两类问题，别混为一谈」判别小节（乱码 → 编码；语法错/找不到文件 → 参数改写）， 并在「不需要包装的工具」白名单下注明：输出编码干净 ≠ 没坑。","fileCount":4,"zipByteSize":12114},{"version":"4.2.0","createdAt":"2026-07-19T16:43:57.851Z","changelog":"v4.2.0 —— 修复 setup-env 的 Windows 用户级环境变量根本没设成功的 bug（嵌套双引号被 cmd.exe 吞掉）；SKILL.md 补充 GBK 遗留文件读取、UTF-8 BOM、Out-File 默认 UTF-16、stdin/InputEncoding、原始字节工具等编码陷阱；CLI 支持多盘 OpenClaw、失败时退出非零、参数解析健壮化；测试全程隔离 HOME 并大幅提升覆盖。","fileCount":5,"zipByteSize":10044},{"version":"4.1.0","createdAt":"2026-06-04T06:18:10.753Z","changelog":"v4.1.0 —— 专治 Windows(GBK/936) 下 LLM 执行命令的编码错误：中文乱码、命令报错、反复重试。修复：setup-env 改用 Windows 用户级环境变量、Python 用 -X utf8、补充 pwsh 说明与环境自检、新增 11 项 CLI 测试。","fileCount":6,"zipByteSize":9184}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s171zews55hjbzfkyz1vv4mg05846nxs:windows-shell","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chenmo0414-windows-shell/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chenmo0414-windows-shell/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chenmo0414-windows-shell/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chenmo0414-windows-shell/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chenmo0414-windows-shell/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chenmo0414-windows-shell/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T14:13:02.139Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chenmo0414-windows-shell/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chenmo0414-windows-shell/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chenmo0414-windows-shell/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chenmo0414-windows-shell/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T11:29:54.514Z","emptyReason":null},"readme":"Skill: windows-shell\n\nOwner: chenmo0414\n\nSummary: Windows 命令行工作规范：先选对 shell（默认 Git Bash），再避开编码与 MSYS2 参数改写两类陷阱。覆盖 GBK/UTF-8、BOM、MSYS2 路径转换、PowerShell/pwsh、WSL 判定、Python/Node.js、Git 配置与代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。细节按需读 references/。\n\nTags: latest:5.3.0\n\nVersion history:\n\nv5.3.0 | 2026-08-20T10:52:34.177Z | user\n\n补两条，否掉一条。候选来自 agent 实测自报的「规范没写、只能靠自有知识现推」，\n再用 TokenHub 多模型探针筛出其中模型真不会的（每格 5 次采样，共 240 次调用）。\n\n**新增 1：`PIPESTATUS` 会被下一条命令重置，包括赋值语句本身。**\n\n    cmd | tail -1; a=${PIPESTATUS[0]}; b=${PIPESTATUS[1]}   # ✗ b 恒为 0\n    cmd | tail -1; st=(\"${PIPESTATUS[@]}\")                  # ✓ 紧邻、一次取完\n\n实测 `(exit 7) | tail -1`：紧邻读得 7，中间隔一条命令再读得 0，先赋值再读第二个也得 0。\n原规范只写了「用 ${PIPESTATUS[0]}」，没说它会失效——三个 agent 都在这上面栽过。\nTokenHub 裸问命中率 40%，加规则后 deepseek 两个模型由 4/5、2/5 拉满到 5/5。\n\n**新增 2（辟谣条目）：中文写在 `-Command '...'` 参数里是安全的，不需要 BOM。**\n\n    powershell -NoProfile -Command '$s=\"中文测试\"; Write-Output $s.Length'   # → 4，正确\n\n要 BOM 的只有**脚本文件**（见 5.2.0），命令行参数走的是另一条路径。这条是反向陷阱：\n实测中有两个 agent 因为担心参数被 ANSI 吃掉，绕道去写带 BOM 的 .ps1，白花两条命令。\nTokenHub 裸问只有 40% 答对——六成情况下模型会误以为会坏。\n\n**否掉：编码判定方法（`od` 看字节区分 GBK/UTF-8）。**\n\n四个 agent 点名「规范没写这个」，但 TokenHub 三模型裸问 **15/15 全对**，两轮复测一致。\n它们不是不知道，是不确定该不该做这一步。写进去纯属浪费篇幅，故不收。\n\n这条同时给出一个方法学结论：**agent 自报的 spec_gaps 不能直接采信**。四条候选里，\n一条被证伪（中文传 -Command 根本不会坏，是 agent 误判）、一条被证明模型早就会\n（od 判编码）、只有两条真该写。全部采信会白白撑大主文件。\n\n**一个需要警惕的信号**：主文件已达 8716 字节，逼近测试守卫的 9000 上限。该上限的依据\n是实测的成本曲线（1.9KB 反弹到 1.01x、6.4KB 最优 0.87x、18KB 是 1.43x），现在已超出\n验证过的最优区间。下次再加内容前应先重测成本，不要直接抬高守卫。\n\n**已知局限**：minimax-m3 在 PIPESTATUS 这条上给了规范仍是 0/5，中文 -Command 那条也只\n到 2/5。另两个模型均为 5/5，故判断为该模型在细节题上的固有弱项，未为其调整措辞。\n\nv5.1.0 | 2026-08-19T16:05:30.011Z | user\n\n新增一条静默失败陷阱，来自一次「能不能砍得更狠」的对照实验。\n\n**PS 5.1 读无 BOM 的 UTF-8 文件，不显式写 `-Encoding UTF8` 会静默算错行数。**\n实测：一个 3 行的 UTF-8 文件，某行末尾字节为 `a1 8c 0a`，PS 按 GBK 把 `8c` 当作\n双字节前导、吞掉紧随的换行，`Get-Content` 返回 **2 行**，而 `$?` 仍是 `True`。\n这不是「可能乱码」那种显眼的错，是结果错但不报错——性质与规则 1 的参数改写完全相同。\n\n原表格里虽有「UTF-8 → `-Encoding UTF8`」一行，但那是当作普通对照写的，读者会以为\n不加只是可能乱码。现升格为显式警告，并在开头的判别表中增设**「静默失败」**一类：\n没报错但结果就是不对（参数变了值、行数少一行）→ 必须交叉验证。\n\n发现过程：为回答「规范还能不能更省」，做了一版 1.9KB 的极简规范（只保留实测中模型\n真正做错的两条）做对照。结果是**砍过头会反弹**：\n\n| 规范 | 命令数 | 总 token（vs 无规范） |\n|------|------|------|\n| 无 | 19.2 | 1.00x |\n| 18 KB 全量 | 15.8 | 1.43x |\n| **6.4 KB 按需（本版基线）** | **11.2** | **0.87x** |\n| 1.9 KB 极简 | 17.5 | 1.01x |\n\n砍掉 4.5KB 省下的阅读量，被多出来的 6.3 条试错命令吃光还倒亏。四个 agent 共列出\n23 条「规范没写、只能靠自有知识补」的缺口——编码判定方法、venv/pytest 具体命令、\nPython 转码写法各被点名 3–4 次。模型确实「会」，但每次现推都要花命令。\n\n结论：**6.4KB 附近就是这套规范的成本最优点**，再砍会反弹。而极简版意外撞出的这条\n静默失败，恰恰证明了「模型自己会」的那些条目不能省——g4 就是栽在被我砍掉的那一行上。\n\nv5.0.0 | 2026-08-19T15:20:06.349Z | user\n\n结构性变更：改为**按需展开**，并把 `windows-shell-routing` 合并进来。\n\n起因是一组 A/B 实测。四臂各跑 4 次同一个 Windows 任务（16 次运行），结论有两条：\n\n- **skill 的作用是精确的，不是普遍的。** 16 次里唯一 100% 分离的指标是「参数被静默改写」\n  这一步——无 skill 组 0/4 一次通过，读了规范的三组 12/12 全部一次通过。其余步骤靠常识\n  也能过，测不出差别。\n- **篇幅不等于价值。** 只读 10KB routing 的一组，总 token 是无 skill 组的 1.09 倍；\n  只读 18KB windows-shell 的一组是 1.43 倍、耗时 1.31 倍——而两组在那个关键步骤上\n  效果完全相同。多出来的 8KB 没有兑现任何行为差异。\n\n所以把一次性全量加载改成按需加载：\n\n- `SKILL.md` 缩到 138 行 / 5.8KB，只保留实测中真正拉开差距的内容：两类问题的判别、\n  shell 选型速查、五条高频规则、一次性环境配置，以及一张「遇到什么读哪个」的索引表。\n- 细节移入 `references/`（25KB，5 个文件）：`encoding.md`、`msys2.md`、\n  `shell-routing.md`、`gitbash-pitfalls.md`、`wsl.md`。规则原文一字未改，只是换了位置。\n- **默认加载量降到原来的 20%**（28.3KB → 5.8KB），完整信息量不减。\n\n合并 `windows-shell-routing`：该技能的全部内容进入 `references/shell-routing.md`、\n`wsl.md`、`gitbash-pitfalls.md`，选型速查表上浮到主文件第二节。之所以能合并，正是因为\n有了按需加载——此前拒绝合并的理由是「两者相加 527 行太长」，那个理由现在不成立了。\n原 slug 走 ClawHub 重定向。\n\n测试相应增加渐进式披露的守卫：主文件体积上限、references 链接必须可解析、不得有孤儿\n文件、以及七个「逃生开关」必须存在于 bundle 中的某处（它们是实测中真正改变了 agent\n行为的部分）。\n\n**发布前做了效果验证，并据此回填了两条。** 首版拆分后重跑同一任务，发现第 1 步\n（GBK 遗留文件转码）的一次通过率从 4/4 掉到 1/4——四个 agent 都正确判出了 GBK，却有\n三个先去试 `iconv`，撞上「Git Bash 没有 iconv」；那条提示被我移进了 references，\n主文件只剩一个指针。同时有三个 agent 点名想查「PS 5.1 怎么写无 BOM 的 UTF-8」，\n主文件只警告了陷阱、没给配方。\n\n于是把这两条回填主文件（新增第 4 条「Git Bash 少几个你以为有的工具」，并在第 3 条\n补上 `WriteAllText` + `UTF8Encoding($false)` 的写法），主文件从 5.8KB 到 6.4KB。\n重跑验证：第 1 步回到 4/4，命令数 11.2（六臂最低），总 token 相对无规范 0.87x\n——**是所有方案里唯一比不用规范还便宜的**。相对拆分前的 18KB 全量版：\ntoken 0.60x、耗时 0.54x、命令 0.71x。\n\n跨模型交叉验证（经腾讯 TokenHub 调 deepseek-v3.2 / v4-flash / v4-pro / kimi-k3 /\nminimax-m3 五个模型，各 6 道知识探针）：回填后「Git Bash 有无 iconv」一题从 1/5\n修正到 5/5。另有一条稳定的发现——`MSYS_NO_PATHCONV` 这个解法，五个模型两轮共 10 次\n裸问**没有一次答对**，而给了规范后 5/5 全对。模型知道参数会被改写，却不知道怎么解决；\n这正是本技能存在的意义所在。\n\n**一个诚实的限制**：两轮共 8 次运行中，agent 读取 references 的次数是 **0**，\n全部自评「主文件够用」。所以当前成立的其实是「主文件压缩到够用 + 附录供人查阅」，\n而不是 agent 会自己按指针去取。今后往 references 放内容需按此前提判断：\n凡是 agent 真正需要的，必须留在主文件里。\n\nv4.4.0 | 2026-08-19T07:49:05.865Z | user\n\n新增 MSYS2 参数改写规则，并修正三处经复测证伪的旧结论。稳定性结论均为 12 次采样，\n不再是单次观察。\n\n修正：\n\n- **pwsh 7 不再标注「输出可能乱码（实测不稳定）」**。实测 12/12 稳定 UTF-8。\n  UTF-8 前缀只对 PS 5.1 必需；外部程序（node/python）的输出穿过 PowerShell 不会被改，\n  两侧都不受影响。规则 1 改为一张按「中文来源 × 是否加前缀」划分的实测表。\n- **`reg query` 移出编码禁用表**。它的失败是 MSYS2 把注册表路径当 Unix 路径改写\n  （报「无效语法」而非乱码），加 `MSYS_NO_PATHCONV=1` 后原命令即可正常工作，与编码无关。\n  规则 3 因此拆为 A 类（真编码问题：wmic/systeminfo/ipconfig/netstat/tasklist/net user）\n  与 B 类（参数改写：reg query/findstr/schtasks），两类解法完全不同。\n- **规则 4 补上前提**。配好用户级 `PYTHONUTF8` 后裸 `python -c` 已经正常；\n  `-X utf8` 的价值在于不依赖环境（CI、容器、别人的机器），而非「不加必乱码」。\n  附反证：清空该变量后 `getpreferredencoding` 立刻退回 `cp936`。\n\n新增（原规则 6/7/8 顺延为 8/9/10）：\n\n- **规则 6：MSYS2 会改写以 `/` 开头的参数**。`/api/v1/users` 被改写成\n  `D:/Program Files/Git/api/v1/users`，`/S /C` 变成 `S:/ C:/`，Docker 的 `-v` 参数被吃掉。\n  最坏的是它**静默生效**——不报错、退出码正常、参数已经变了。给出\n  `MSYS_NO_PATHCONV` / `MSYS2_ARG_CONV_EXCL` / 双斜杠三种解法，并说明为什么不能全局导出\n  （会让 `/c/Users/...` 这类本该转换的参数也不转）。\n- **规则 7：`ln -s` 默认产出普通文件副本**，影响 pnpm workspace / npm link；\n  `MSYS=winsymlinks:nativestrict` 可修，附开发者模式检查命令。\n\n另新增开头的「两类问题，别混为一谈」判别小节（乱码 → 编码；语法错/找不到文件 → 参数改写），\n并在「不需要包装的工具」白名单下注明：输出编码干净 ≠ 没坑。\n\nv4.2.0 | 2026-07-19T16:43:57.851Z | user\n\nv4.2.0 —— 修复 setup-env 的 Windows 用户级环境变量根本没设成功的 bug（嵌套双引号被 cmd.exe 吞掉）；SKILL.md 补充 GBK 遗留文件读取、UTF-8 BOM、Out-File 默认 UTF-16、stdin/InputEncoding、原始字节工具等编码陷阱；CLI 支持多盘 OpenClaw、失败时退出非零、参数解析健壮化；测试全程隔离 HOME 并大幅提升覆盖。\n\nv4.1.0 | 2026-06-04T06:18:10.753Z | user\n\nv4.1.0 —— 专治 Windows(GBK/936) 下 LLM 执行命令的编码错误：中文乱码、命令报错、反复重试。修复：setup-env 改用 Windows 用户级环境变量、Python 用 -X utf8、补充 pwsh 说明与环境自检、新增 11 项 CLI 测试。\n\nArchive index:\n\nArchive v5.3.0: 9 files, 28486 bytes\n\nFiles: CHANGELOG.md (14776b), references/encoding.md (12160b), references/gitbash-pitfalls.md (2525b), references/msys2.md (3455b), references/shell-routing.md (5061b), references/wsl.md (1929b), skill-card.md (2555b), SKILL.md (8716b), _meta.json (132b)\n\nFile v5.3.0:SKILL.md\n\n---\nname: windows-shell\nversion: 5.3.0\ndescription: \"Windows 命令行工作规范：先选对 shell（默认 Git Bash），再避开编码与 MSYS2 参数改写两类陷阱。覆盖 GBK/UTF-8、BOM、MSYS2 路径转换、PowerShell/pwsh、WSL 判定、Python/Node.js、Git 配置与代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。细节按需读 references/。\"\nlicense: MIT\nmetadata:\n  openclaw:\n    emoji: \"🪟\"\n    os: [windows]\n    homepage: \"https://github.com/Chenmo0414/win-encoding-fix\"\n---\n\n# Windows 命令行工作规范\n\n用户系统：Windows 10/11（代码页 GBK/936），终端：MSYS2/Git Bash。\n\n**本文件是速查与路由表。** 每条规则下面标了「细读」，只在真正遇到那类问题时再去读对应的\n`references/` 文件——不要一次性全部读完。\n\n## 一、先分清是哪一类问题\n\n在 Git Bash 里执行命令出问题，绝大多数是这两类之一。**先判类，再套解法**，两类的解法完全不通用：\n\n| 症状 | 类别 | 第一反应 |\n|------|------|------|\n| 输出乱码（`涓枃`、`M-DM-c`、方块字） | **编码** | 让源头输出 UTF-8 |\n| 没报错但**结果就是不对**（参数变了值、行数少一行） | **静默失败** | 见第 1、3 条，必须交叉验证 |\n| 报「无效语法 / invalid / 找不到文件」，或参数悄悄变了值 | **MSYS2 参数改写** | `MSYS_NO_PATHCONV=1` |\n\n拿编码的解法去治参数改写，怎么加前缀都不好使——这是最常见的误诊。\n\n## 二、选对 shell（默认 Git Bash）\n\n| 你要做的事 | 用哪个 |\n|------|------|\n| npm / node / npx / tsc / vitest / python / pip / pytest / git / ssh | **Git Bash** |\n| Windows 服务、注册表、事件日志、计划任务、证书、.NET/COM、对象管道 | **PowerShell**（单条命令切过去，主线不搬家） |\n| 跑 Makefile、需要 gcc/rsync，或重 I/O 构建且项目能整个搬进 ext4 | **WSL** |\n| 需要管理员权限 | **交给人做**——UAC 弹窗 agent 点不了，命令会一直挂着 |\n\n项目文件在 `C:\\`/`D:\\` 上时，**不要用 WSL 去操作它**：跨 `/mnt/*` 比纯 Windows 还慢 4–6 倍，\n且惩罚随项目规模线性放大。\n\n> 细读：判断依据与完整决策表 → [shell-routing.md](references/shell-routing.md)；\n> WSL 值不值得上 → [wsl.md](references/wsl.md)\n\n## 三、必须知道的六条\n\n下面六条是实测中真正拉开差距的。其余规则都在 `references/`。\n\n### 1. 以 `/` 开头的参数会被静默改写\n\nGit Bash 把它当 Unix 路径转成 Windows 路径再传给原生程序。**不报错、退出码 0、参数已经变了**：\n\n```bash\nnode app.js /api/v1/users          # 程序实收 D:/Program Files/Git/api/v1/users\ndocker run -v /app:/app ...        # -v 后面被吃掉\nreg query \"HKCU\\Environment\"       # 错误: 无效语法。\n```\n\n```bash\nMSYS_NO_PATHCONV=1 node app.js /api/v1/users    # 单条前置，不要全局导出\n```\n\n全局导出会让 `/c/Users/...` 这类本该转换的参数也不转。\n\n> 细读：另两种绕法、符号链接退化 → [msys2.md](references/msys2.md)\n\n### 2. PowerShell 5.1 输出中文必须加前缀\n\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; 你的命令'\n```\n\n外层用**单引号**（防 bash 展开 `$_`、`$null`）。pwsh 7 不需要这个前缀，加了也无害。\n外部程序（node/python）自己写的 UTF-8 穿过 PowerShell 不会被改。\n\n### 3. 读遗留文件前先验编码，别硬套 UTF-8\n\n对一个真正的 GBK/936 文件强加 `-Encoding UTF8` 会读出乱码。先看字节再决定：\n\n```bash\nod -c legacy.txt | head -2        # 或 xxd；Git Bash 没有 hexdump\n```\n\n| 文件真实编码 | PS 5.1 | pwsh 7 |\n|------|------|------|\n| UTF-8 | `-Encoding UTF8`（**必须显式写**） | 默认即可 |\n| GBK/936 | `-Encoding Default` | `[System.Text.Encoding]::GetEncoding(936)` |\n\n**PS 5.1 读无 BOM 的 UTF-8 不加 `-Encoding UTF8` 会静默出错**——不是乱码那么显眼，\n而是行数直接算错、退出码仍为 0。实测：一个 3 行的 UTF-8 文件，某行末尾字节是\n`a1 8c 0a`，PS 按 GBK 把 `8c` 当双字节前导、吞掉紧随的换行，`Get-Content` 返回\n**2 行**且 `$?` 为 `True`。性质与上面第 1 条的参数改写相同：**结果错、不报错**。\n所以 **PS 5.1 读任何文本文件都显式指定 `-Encoding`**，别赌默认值。\n\n**含中文的 `.ps1` 脚本文件必须存成 UTF-8 with BOM**。PS 5.1 读脚本时没有 BOM 就按\nANSI/GBK 解析，中文字面量被拆错——而且多数情况**不报错**：\n\n```\n同一段 $s = \"腾讯\"，只差 BOM：\n  PS 5.1 无 BOM  →  $s.Length = 3   ✗   字符串在内存里是 3 个错字符\n  PS 5.1 有 BOM  →  $s.Length = 2   ✓\n```\n\n最阴险的是 `Write-Output $s` **打印出来是对的**——脚本按 GBK 误读、输出时又按 GBK 编码，\n两次错误相互抵消。但凡是取长度、截取、正则、比较、哈希的地方全是错的。\n（历史会话里这条也会以 `Unexpected token '鑵捐'` 的语法错形式爆出来，那只是误读的字节\n恰好构成非法 token 的少数情况。）pwsh 7 默认按 UTF-8 读脚本，无此问题。\n\n**只影响脚本文件，不影响命令行参数。** 中文直接写在 `-Command '...'` 里是安全的：\n\n```bash\npowershell -NoProfile -Command '$s=\"中文测试\"; Write-Output $s.Length'   # → 4，正确\n```\n\n这条容易被反向误判——实测有 agent 因为担心参数被 ANSI 吃掉，绕道去写带 BOM 的 `.ps1`，\n白花两条命令。**要 BOM 的是脚本文件，`-Command` 参数不用。**\n\n**写出去也有坑**：PS 5.1 的 `-Encoding UTF8` 会带 BOM，`>` 重定向默认写 UTF-16。要无 BOM 的 UTF-8：\n\n```powershell\n[System.IO.File]::WriteAllText(\"out.txt\", $s, (New-Object System.Text.UTF8Encoding($false)))\n```\n\n> 细读：更多 BOM/重定向陷阱、`$OutputEncoding`、传统 CMD 工具替代表\n> → [encoding.md](references/encoding.md)\n\n### 4. Git Bash 少几个你以为有的工具\n\n`iconv`、`jq`、`make`、`gcc`、`rsync`、`hexdump` **都没有**。转码不要指望 `iconv`，\n验字节用 `od -c`，其余场景改用 Python 或 Node 顶上；真需要完整 GNU 工具链就上 WSL。\n\n```bash\npython -c \"import io;io.open('out.txt','w',encoding='utf-8').write(io.open('in.txt',encoding='gbk').read())\"\n```\n\n### 5. 生成代码时显式写编码，不依赖环境\n\n```python\nopen('data.txt', encoding='utf-8')          # 裸 open() 在 Windows 上默认 cp936\n```\n\n```bash\npython -X utf8 -c \"...\"                      # 单行命令，不假设 PYTHONUTF8 已生效\n```\n\n环境变量会失效，代码里的显式声明不会。\n\n### 6. venv 直接调解释器，绕开 activate\n\n```bash\n./.venv/Scripts/python.exe -m pytest         # source activate 会拼出正反斜杠混拼的畸形路径\n```\n\n同理，管道会吞掉上游退出码，要用 `set -o pipefail` 或 `${PIPESTATUS[0]}`。\n**但 `PIPESTATUS` 会被下一条命令重置——包括赋值语句本身**：\n\n```bash\ncmd | tail -1; a=${PIPESTATUS[0]}; b=${PIPESTATUS[1]}   # ✗ b 恒为 0，赋值 a 就把数组冲了\ncmd | tail -1; st=(\"${PIPESTATUS[@]}\")                  # ✓ 紧邻、一次取完\necho \"上游=${st[0]} 下游=${st[1]}\"\n```\n\n实测：`(exit 7) | tail -1` 后紧邻读得 7；中间隔一条命令再读得 0。\n\n> 细读：venv、工具集不全、SSH 密钥、符号链接 → [gitbash-pitfalls.md](references/gitbash-pitfalls.md)\n\n## 四、一次性环境配置\n\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8;\n  [Environment]::SetEnvironmentVariable(\"PYTHONUTF8\", \"1\", \"User\");\n  [Environment]::SetEnvironmentVariable(\"PYTHONIOENCODING\", \"utf-8\", \"User\")'\ngit config --global core.quotepath false\ngit config --global core.autocrlf input\n```\n\n写进 `~/.bash_profile` 的变量**非登录 shell 不会加载**（agent 正是这种 shell），\n所以要设成 Windows 用户级环境变量。\n\n> 细读：完整配置与每条的理由 → [encoding.md](references/encoding.md) 的「环境前置条件」\n\n## 五、按需索引\n\n| 遇到什么 | 读哪个 |\n|------|------|\n| 乱码、BOM、UTF-16、GBK 遗留文件、CMD 工具替代 | [encoding.md](references/encoding.md) |\n| 参数被改写、符号链接变成副本 | [msys2.md](references/msys2.md) |\n| 不确定该用哪个 shell、想看实测依据 | [shell-routing.md](references/shell-routing.md) |\n| venv、工具缺失、SSH 密钥、管道退出码 | [gitbash-pitfalls.md](references/gitbash-pitfalls.md) |\n| 要不要上 WSL、`wsl.exe` 变量吞噬 | [wsl.md](references/wsl.md) |\n\nFile v5.3.0:_meta.json\n\n{\n  \"ownerId\": \"kn78ryxatfm99gvwnvgexh8hkx847bk7\",\n  \"slug\": \"windows-shell\",\n  \"version\": \"5.3.0\",\n  \"publishedAt\": 1787223154177\n}\n\nFile v5.3.0:references/encoding.md\n\n# 编码细节（GBK / UTF-8 / BOM）\n\n主文件 `SKILL.md` 只放了最常用的两条。遇到下列任一情况时读本文：\n读写文件出现乱码、需要处理 GBK 遗留文件、需要写无 BOM 的 UTF-8、\nPowerShell 重定向编码不对、管道方向的编码问题、传统 CMD 工具输出乱码。\n\n## 环境自检（开工前可选执行）\n\n判断当前 shell 的编码是否已正确配置：\n\n```bash\npython -c \"import sys; print('utf8_mode=', sys.flags.utf8_mode)\"   # 期望 1；为 0 说明 Python 默认 GBK\necho \"PYTHONUTF8=$PYTHONUTF8\"                                       # 期望 1；为空说明环境变量未加载\n```\n\n**关键认知**：`PYTHONUTF8` 等变量若只写在 `~/.bash_profile`，**非登录 / 非交互 shell 不会加载它**（AI 助手与脚本通常正是这种 shell）。因此：\n\n- 持久生效请配置 **Windows 用户级环境变量**（被所有进程继承，重启终端后生效）；\n- 当前会话内最可靠的做法是**每条命令显式带编码参数**（见下方各规则）。\n\n## 环境前置条件（持久配置，建议一次性执行）\n\n```bash\n# 1) Windows 用户级环境变量 —— 最可靠，所有进程继承（重启终端后生效）\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8;\n  [Environment]::SetEnvironmentVariable(\"PYTHONUTF8\", \"1\", \"User\");\n  [Environment]::SetEnvironmentVariable(\"PYTHONIOENCODING\", \"utf-8\", \"User\")'\n\n# 2) bash 显示相关变量（登录 shell 用），并让 .bashrc 也加载，覆盖非登录交互 shell\ncat >> ~/.bash_profile <<'EOF'\nexport PYTHONUTF8=1\nexport PYTHONIOENCODING=utf-8\nexport LANG=en_US.UTF-8\nexport LESSCHARSET=utf-8\nEOF\ngrep -q 'bash_profile' ~/.bashrc 2>/dev/null || echo '[ -f ~/.bash_profile ] && . ~/.bash_profile' >> ~/.bashrc\n\n# 3) Git 全局配置\ngit config --global core.quotepath false        # 中文文件名正常显示\ngit config --global core.autocrlf input         # 提交 LF，检出保持原样\ngit config --global i18n.commitEncoding utf-8    # commit 消息 UTF-8\ngit config --global i18n.logOutputEncoding utf-8\ngit config --global core.pager \"less -R\"\n```\n\n> 一键配置：在 [skill-factory](https://github.com/Chenmo0414/win-encoding-fix) 仓库里执行 `node bin/cli.js setup-env`\n\n### 规则 1：PowerShell 命令必须加 UTF-8 前缀 + 外层单引号\n\n```bash\n# 标准模板（外层单引号 + UTF-8 前缀）\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; 你的命令'\n```\n\n**两个要点必须同时满足：**\n- `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8` — 不加则中文输出乱码\n- 外层**单引号** — 防止 bash 把 `$_`、`$null` 当作 bash 变量展开\n\n仅当命令中不含 `$` 变量时才可用外层双引号。\n\n**前缀到底什么时候必需**（v4.3.0 实测，各采样 12 次，结果完全稳定）：\n\n| 中文的来源 | PS 5.1 无前缀 | PS 5.1 加前缀 | pwsh 7 无前缀 |\n|------|------|------|------|\n| PowerShell 自己产出（`Write-Output`、cmdlet 结果） | **GBK ×12 → 乱码** | UTF-8 ×12 ✅ | **UTF-8 ×12 ✅** |\n| 外部程序产出（`node -e`、`python` 等） | UTF-8 ×12 ✅ | UTF-8 ×12 ✅ | UTF-8 ×12 ✅ |\n\n- **PS 5.1 必须加前缀**：只要中文由 PowerShell 自己产出，不加就是稳定乱码，没有侥幸。\n- **pwsh 7 不需要前缀**：实测 12/12 稳定 UTF-8。加了无害，脚本要兼容 5.1 时统一加是合理的，但不必因为「怕 pwsh 不稳」而加。\n- **外部程序的输出不受影响**：`node`/`git`/`python` 自己写 UTF-8 到 stdout，穿过 PowerShell 不会被改。所以「PS 包装」只对遵守控制台代码页的 Windows 原生工具才有意义（见规则 3）。\n\n### 规则 2：PowerShell 读写文件 —— `-Encoding` 必须匹配文件真实编码\n\n**读 UTF-8 文件**：PowerShell 5.1 不加 `-Encoding UTF8` 会用 GBK 读取，实测 `中文` → `涓枃`。\n\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Content \"path\\file.txt\" -Encoding UTF8'\n```\n\n**⚠️ 读 GBK 遗留文件（本机最常见）**：反过来，对一个真正的 GBK/936 文件强加 `-Encoding UTF8` 会**读出乱码**。`-Encoding` 的值必须等于文件的真实编码：\n\n| 文件真实编码 | PS 5.1 读法 | pwsh 7 读法 |\n|------|------|------|\n| UTF-8 | `-Encoding UTF8` | 默认即可（或 `-Encoding utf8`） |\n| GBK/936（遗留） | `-Encoding Default` 或不加 | `-Encoding oem` 或 `[System.Text.Encoding]::GetEncoding(936)` |\n\npwsh 7 默认按 UTF-8 读，遇到 GBK 文件反而会 mojibake，此时**必须显式指定 936**。\n\n**写文件的 BOM 陷阱**：PS 5.1 的 `Set-Content -Encoding UTF8` / `Out-File -Encoding UTF8` 会写入 **UTF-8 BOM**（`EF BB BF`），很多工具（旧编译器、某些 JSON 解析器、shell 脚本）会因此报错。要写**无 BOM** UTF-8：\n\n```powershell\n# PS 5.1 无 BOM 写法\n[System.IO.File]::WriteAllText(\"out.txt\", $content, (New-Object System.Text.UTF8Encoding($false)))\n# pwsh 7\nSet-Content out.txt -Value $content -Encoding utf8NoBOM\n```\n\n**输出重定向的编码**：PS 5.1 的 `>` 和 `Out-File` **默认写 UTF-16 LE**，不是 UTF-8。若要把命令输出存成 UTF-8 文件给后续读取，务必显式 `... | Out-File -Encoding utf8 out.txt`（注意上面的 BOM 说明），或捕获字符串后用 .NET 写。\n\n**stdin / 管道方向**：`[Console]::OutputEncoding` 只管 PowerShell **输出**。若要把 UTF-8 内容通过管道**喂进** PowerShell（`echo ... | powershell ...`），还需 `[Console]::InputEncoding = [System.Text.Encoding]::UTF8`；而 PowerShell **管道给下游原生命令**（如 `... | findstr`）用的是 `$OutputEncoding` 变量（默认 ASCII，会丢中文）。能用内联 `-Command` 参数就别走 stdin 管道。\n\n### 规则 3：禁止直接使用传统 CMD 工具和 cmd /c\n\n传统 CMD 工具多数输出 GBK 或 UTF-16，在 UTF-8 终端中乱码。`cmd /c` 同样不可用——`chcp 65001` 无法修复子进程编码（实测 `cmd /c \"chcp 65001 & echo 你好\"` 仍乱码）。\n\n但**并非全都是编码问题**。实测把它们分成了两类，解法完全不同：\n\n**A 类 —— 真·编码问题**（实测输出 GBK 字节，PS 包装可解决）：\n\n| 禁止 | 替代 |\n|------|------|\n| `wmic` | `Get-CimInstance` |\n| `systeminfo` | `Get-ComputerInfo` 或 PS 包装 `systeminfo` |\n| `ipconfig` | `Get-NetIPAddress` / `Get-NetIPConfiguration` |\n| `netstat` | `Get-NetTCPConnection` |\n| `tasklist` | `Get-Process` |\n| `net user` | `Get-LocalUser` |\n| `sc query` | `Get-Service`（英文输出时不乱码，但中文服务名会） |\n| `cmd /c` | **永远不用** |\n\n**B 类 —— 其实是 MSYS2 参数改写，不是编码问题**（实测：加 `MSYS_NO_PATHCONV=1` 后原命令即可正常工作）：\n\n| 命令 | 默认失败表现 | 真实原因 |\n|------|------|------|\n| `reg query \"HKCU\\Environment\"` | `错误: 无效语法。` | 注册表路径被当成 Unix 路径改写 |\n| `findstr 中文 /tmp/x.txt` | `FINDSTR: 无法打开 C:x.txt` | `/tmp/x.txt` 被改写成 `C:x.txt` |\n| `schtasks /query /tn \"\\...\"` | 参数错误 | 同上 |\n\nB 类仍然**建议**换成 `Get-ItemProperty` / `Select-String` / `Get-ScheduledTask`——PowerShell 版本输出更结构化、也不受 MSYS2 影响。但要知道：**它们不是「因为乱码」才被禁的**，误诊会让你在别处用错解法（比如给一个路径被改写的命令拼命加编码前缀，怎么加都不好使）。\n\n在 PowerShell 中包装传统命令**通常**可正确转码：\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; systeminfo | Select-Object -First 5'\n```\n\n> **注意，包装不是万能的**：`[Console]::OutputEncoding` 只对**遵守控制台输出代码页**的工具有效（`systeminfo`、`ipconfig` 等）。对于**输出固定 GBK 字节或原始字节**的工具（部分第三方 CLI、某些日志），包装后仍是乱码——这类需要「先按 936 解码、再转 UTF-8」：`powershell -Command '$s = (& some.exe) ; [Console]::OutputEncoding = [System.Text.Encoding]::UTF8; [System.Text.Encoding]::GetEncoding(936).GetString(...)'`，或在 Node/Python 侧以**字节**捕获再按真实编码解码（见规则 5、规则 9）。\n\n### 规则 4：Python 命令行执行 —— 优先 `-X utf8`，不要假设环境\n\n实测：AI 助手与脚本运行在**非交互 shell**，若 `PYTHONUTF8` 只写在 `~/.bash_profile`，它不会被加载，`sys.flags.utf8_mode` 为 0，`python -c \"print('你好')\"` 直接乱码。\n\n**注意前提**：一旦按上文「环境前置条件」把 `PYTHONUTF8` 配成了 **Windows 用户级环境变量**，裸 `python -c \"print('你好')\"` 就已经正常了（实测 `utf8_mode=1`、`getpreferredencoding=utf-8`）。所以 `-X utf8` 的价值不是「不加就一定乱码」，而是**不依赖环境是否配好**——在别人的机器、CI、容器里同样成立。这也正是它值得默认带上的理由。\n\n反证：把 `PYTHONUTF8` 清空后再测，`getpreferredencoding` 立刻退回 `cp936`。环境配置是会失效的，代码里的显式声明不会。\n\n**最可靠做法 —— 单行命令显式带 `-X utf8`：**\n```bash\npython -X utf8 -c \"print('你好世界')\"\n# 或临时设环境变量\nPYTHONUTF8=1 python script.py\n```\n\n`-X utf8` 同时让 `print()` 输出与 `open()` 默认读写都走 UTF-8，幂等无副作用，已是 UTF-8 环境时加它也不会出错。**生成代码时**仍应显式写 `encoding='utf-8'`（见规则 8），不依赖运行时标志。\n\n### 规则 5：Node.js 子进程调用系统命令\n\nNode.js 自身输出 UTF-8 没问题，但 `execSync`/`exec`/`spawn` 调用传统 CMD 工具时，输出是 GBK，`toString('utf-8')` 会乱码。\n\n**修复**：让子进程通过 PowerShell 输出 UTF-8：\n```javascript\nexecSync('powershell -Command \"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; systeminfo\"').toString('utf-8')\n```\n\n对于**输出原始 GBK 字节、不认控制台代码页**的工具，PowerShell 包装无效，应以字节捕获再手动解码：\n```javascript\nconst { execSync } = require('child_process')\nconst buf = execSync('some-gbk-tool.exe')       // 拿 Buffer，不要直接 toString\nconst text = new TextDecoder('gbk').decode(buf)  // 按真实编码解码\n```\n\n### 规则 8：Python 文件 I/O 必须指定编码\n\n```python\n# 正确 — 显式指定 encoding\nwith open('data.txt', 'r', encoding='utf-8') as f:\n    content = f.read()\n\nwith open('output.txt', 'w', encoding='utf-8') as f:\n    f.write(content)\n\n# 错误 — 裸 open() 在 Windows 上默认 GBK（实测 locale.getpreferredencoding() = cp936）\nwith open('data.txt', 'r') as f:  # 不要这样写\n    content = f.read()\n```\n\n同样适用于 `json.load`/`json.dump`、`csv.reader`、`pathlib.Path.read_text()` 等需要文件对象的场景。\n\nPython subprocess 调用系统命令时也需注意编码：\n```python\nimport subprocess\nresult = subprocess.run(\n    ['powershell', '-Command', '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Process'],\n    capture_output=True, text=True, encoding='utf-8'\n)\n```\n\n### 规则 9：Node.js 文件操作和子进程编码\n\n```javascript\n// 文件读写 — 显式指定 utf-8\nfs.readFileSync('data.txt', 'utf-8')\nfs.writeFileSync('output.txt', content, 'utf-8')\n\n// 子进程调用 Windows 原生命令 — 通过 PowerShell 包装\nconst { execSync } = require('child_process')\nconst output = execSync(\n  'powershell -Command \"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Service\"'\n).toString('utf-8')\n```\n\n### 规则 10：Git 中文支持\n\n环境已配置 `core.quotepath=false`，中文文件名在 `git status`/`git diff` 中正常显示。\n\n如果发现中文文件名仍显示为 `\\346\\265\\213\\350\\257\\225` 形式，执行：\n```bash\ngit config --global core.quotepath false\n```\n\n## 格式化技巧\n\n- 宽表格加 `| Out-String -Width 200` 防截断\n- `Format-Table -AutoSize` 自适应列宽\n- `Format-List` 展示详细单条记录\n- `Select-Object` 控制返回字段数量\n\nFile v5.3.0:references/gitbash-pitfalls.md\n\n# Git Bash 的五个坑\n\n在 Git Bash 下遇到非编码类异常时读本文：参数被改写、符号链接失效、\nvenv 激活路径异常、工具缺失、SSH 密钥不通用、管道吞退出码。\n\n## Git Bash 的五个坑\n\n选了 Git Bash，这五个必须知道，否则会以为是代码的问题。\n\n### 坑 1：以 `/` 开头的参数会被改写（静默）\n\nMSYS2 把它们当 Unix 路径转成 Windows 路径再传给程序。**不报错、退出码正常、参数已经变了**：\n\n```bash\nnode app.js /api/v1/users     # 程序收到 D:/Program Files/Git/api/v1/users\nprog /S /C                    # → S:/ C:/\ndocker run -v /app:/app ...   # -v 后面被吃掉\n```\n\n```bash\n# 解法：单条命令前置，别全局导出\nMSYS_NO_PATHCONV=1 node app.js /api/v1/users\n```\n\n全局导出会让 `/c/Users/...` 这类你确实希望被转换的参数也不转了。\n\n### 坑 2：`ln -s` 默认产出的是副本\n\n```bash\nln -s t.txt l.txt && ls -l l.txt      # -rw-r--r--  ← 是副本，不是链接\nexport MSYS=winsymlinks:nativestrict  # 修复后 → lrwxrwxrwx\n```\n\n**pnpm workspace、npm link、monorepo 本地依赖都依赖真符号链接**，退化成副本会表现为「改了源码不生效」。需先启用 Windows 开发者模式。\n\n### 坑 3：venv 的 `activate` 会拼出畸形路径\n\n```bash\nsource .venv/Scripts/activate    # VIRTUAL_ENV 丢盘符，路径变成 /d/proj/\\proj\\.venv/Scripts/python\n```\n\n虽然仍能解析，但不可靠。**直接调解释器，绕开 activate**：\n\n```bash\n./.venv/Scripts/python.exe -m pytest\n./.venv/Scripts/python.exe -m pip install -r requirements.txt\n```\n\n### 坑 4：工具集不全\n\n`jq`、`make`、`gcc`、`rsync` 都**没有**。跑 Makefile 的项目直接卡住——那种情况上 WSL，不要试图在 Git Bash 里凑。\n\n### 坑 5：SSH 密钥位置与 WSL 不通用\n\nGit Bash 与 Windows 共用 `C:\\Users\\你\\.ssh`，**WSL 用的是独立的 `/root/.ssh`**。在 Windows 配好的 SSH，到 WSL 里等于从零开始。\n\n而且 `/mnt/*` 上的文件在 WSL 眼里权限是 `777`，OpenSSH 会判定 `bad permissions` 直接忽略该密钥。要在 WSL 里用 ssh，密钥必须复制到 ext4 并 `chmod 600`。Git Bash 没有这个问题（它走 Windows ACL，不看 POSIX 权限位）。\n\n### 附：管道会吞掉退出码\n\n这不是 Git Bash 特有，但 agent 最容易在这里误判成功：\n\n```bash\nnpm install ... | tail -25      # $? 是 tail 的，不是 npm 的\nset -o pipefail                 # 或用 ${PIPESTATUS[0]}\n```\n\nFile v5.3.0:references/msys2.md\n\n# MSYS2 参数改写与符号链接\n\n主文件已给出 `MSYS_NO_PATHCONV=1` 这一条速查。需要完整解释、\n其它两种绕法、或遇到符号链接/工具缺失问题时读本文。\n\n### 规则 6：MSYS2 会改写以 `/` 开头的参数\n\nGit Bash（MSYS2）在把参数交给 **非 MSYS2 程序**（即所有 Windows 原生 .exe）之前，会把看起来像 Unix 路径的参数自动转换成 Windows 路径。这是 MSYS2 的设计，不是 bug——但它**静默生效**，不报错、退出码正常，参数已经变了。\n\n```bash\nnode app.js /api/v1/users\n# 程序实际收到：D:/Program Files/Git/api/v1/users   ← 前面被拼上了 Git 安装目录\n\nprog /S /C                  # → 变成  S:/ C:/\ndocker run -v /app:/app ... # → -v 后面的参数被破坏\nreg query \"HKCU\\Environment\"   # → 错误: 无效语法。\nfindstr 中文 /tmp/x.txt        # → FINDSTR: 无法打开 C:x.txt\n```\n\n**什么时候会中招**：参数以 `/` 开头，且接收方是 Windows 原生程序。典型场景——REST 路径、Docker 卷映射、Windows 风格开关（`/S` `/C` `/query`）、注册表路径、传给 `.exe` 的 Unix 路径。\n\n**三种解法**（均实测有效）：\n\n```bash\n# A. 单条命令临时关闭（推荐，作用域最小）\nMSYS_NO_PATHCONV=1 reg query \"HKCU\\Environment\" /v PYTHONUTF8\nMSYS_NO_PATHCONV=1 node app.js /api/v1/users\n\n# B. 按参数排除\nMSYS2_ARG_CONV_EXCL='*' node app.js /api/v1/users\n\n# C. 双斜杠转义（只想保护单个参数时）\nnode app.js //api/v1/users\n```\n\n**不要全局导出 `MSYS_NO_PATHCONV=1`**：关掉转换后，`/c/Users/...` 这类你确实希望被转成 `C:\\Users\\...` 的参数也不再转换，会引入另一批问题。按需在单条命令前加。\n\n> 与编码问题的区别：编码问题表现为**乱码**，参数改写表现为**语法错/找不到文件/行为不对但不报错**。诊断时先看报错形态，别拿编码的解法去治路径的病。\n\n### 规则 7：Git Bash 的 `ln -s` 默认产出的是副本\n\n```bash\nln -s t.txt l.txt && ls -l l.txt\n# 默认：  -rw-r--r--  ← 普通文件副本，不是链接\n```\n\n对普通脚本无所谓，但 **pnpm workspace、npm link、monorepo 的本地依赖都依赖真符号链接**，退化成副本会导致改了源码却不生效、或磁盘占用异常。\n\n```bash\n# 修复：产出真正的符号链接（lrwxrwxrwx）\nexport MSYS=winsymlinks:nativestrict\nln -s t.txt l.txt && ls -l l.txt      # → lrwxrwxrwx ... l.txt -> t.txt\n```\n\nWindows 10/11 需先启用**开发者模式**（设置 → 隐私和安全性 → 开发者选项），否则创建符号链接要管理员权限。检查是否已启用：\n\n```bash\npowershell -NoProfile -Command '(Get-ItemProperty \"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock\").AllowDevelopmentWithoutDevLicense'\n# 返回 1 = 已启用\n```\n\n## 不需要包装的工具\n\n以下工具本身输出 UTF-8，可直接使用：\n- `git`、`node`、`npm`、`pnpm`、`bun`、`cargo`、`go`\n- bash 内置：`echo`、`cat`、`ls`、`grep` 等\n- `python`：加 `-X utf8` 后可直接使用（见规则 4）\n\n> **编码没问题 ≠ 完全没坑**：这些工具的**输出编码**是干净的，但只要给它们传以 `/` 开头的参数，\n> 仍会被 MSYS2 改写（见规则 6）；`pnpm` 的 workspace 还依赖真符号链接（见规则 7）。\n> 两件事互相独立，别因为「这个工具在白名单里」就放松警惕。\n\nFile v5.3.0:references/shell-routing.md\n\n# Shell 选型（Git Bash / PowerShell / WSL）\n\n主文件给了速查表。需要判断依据、完整决策表、或想知道为什么默认 Git Bash 时读本文。\n\n## 为什么默认 Git Bash\n\n四个独立 agent 在同一台 Windows 10 机器上做同一份任务（zod + TypeScript + vitest，pydantic + pytest，共 9 步），每个只准用一种 shell。实测结果：\n\n| 执行方式 | 输出 token | 轮次 | 失败 | 重试 | 三道闸门 |\n|------|------|------|------|------|------|\n| **Git Bash** | **8,114（基准）** | **34** | **0** | **0** | 全过 |\n| WSL → `/mnt/d` | 11,543（1.42x） | 34 | 0 | 1（静默） | 全过 |\n| WSL → ext4 | 15,159（1.87x） | 49 | 1 | 2 | 全过 |\n| pwsh 7 | 18,808（**2.32x**） | 46 | 0 | 0 | 全过 |\n\n另一组 12 个典型场景的合成基准独立复现了同一系数：PowerShell 5.1 的输出体积是 POSIX 的 **2.22 倍**（同一个「文件不存在」错误，POSIX 是 50 字节一行，PS 5.1 是 370 字节七行）。\n\n命令启动开销（中位数，发 100 条命令的累计代价）：\n\n| Git Bash | `wsl.exe` | PowerShell 5.1 | pwsh 7 |\n|------|------|------|------|\n| 0.064s（6.4s） | 0.130s（13.0s） | 0.189s（18.9s） | 0.216s（21.6s） |\n\n三条结论：\n\n- **Git Bash 是唯一零失败零重试的一臂**，且 token 最省。\n- **PowerShell 不是「更容易出错」，而是「更啰嗦」**——它同样零失败，但写同样的东西用了 80 条语句（Git Bash 38 条），错误对象带调用栈、字符位置、CategoryInfo、FullyQualifiedErrorId 一起打印。\n- **token 消耗与文件系统快慢无关，只与踩坑次数有关**：跑在最快的 ext4 上那一臂，因为踩了两个 `wsl.exe` 的坑、多花 15 轮，反而 token 最高。\n\n## 决策表\n\n| 你要做的事 | 用哪个 | 理由 |\n|------|------|------|\n| npm / pnpm / node / npx / tsc / vitest / jest | **Git Bash** | 直通，零摩擦 |\n| python / pip / venv / pytest | **Git Bash** | 直通（venv 见下方坑 3） |\n| git 全套 | **Git Bash** | 原生，且 worktree 在 WSL 里根本用不了 |\n| **native 模块编译**（node-gyp + MSVC） | **Git Bash** | 与 pwsh **完全等价**：产物字节数相同，都经 vswhere 找到同一套 VS 工具链 |\n| ssh / scp / git over ssh | **Git Bash** | 与 Windows 共用 `~/.ssh`，密钥无需 chmod（见坑 5） |\n| curl / grep / sed / awk / find / jq* | **Git Bash** | POSIX 工具链（`jq` 需另装，见坑 4） |\n| Windows 服务、注册表、事件日志、计划任务、证书 | **PowerShell** | Git Bash 没有对应能力 |\n| 需要 .NET 类型 / COM 对象 / 对象管道 | **PowerShell** | 硬边界，无替代 |\n| 需要管理员权限 | **交给人做** | UAC 弹窗 agent 点不了，命令会挂死 |\n| 跑 Makefile / 需要 gcc、rsync | **WSL** | Git Bash 的 MSYS2 工具集撑不住 |\n| 重 I/O 的构建（大型 monorepo 反复编译） | **WSL + 项目放 ext4** | 见下方「什么时候才值得上 WSL」 |\n\n## 必须切 PowerShell 的四类\n\n这四类没有 Git Bash 替代品，别硬试：\n\n1. **Windows 系统层面** —— `Get-Service` / `Get-ScheduledTask` / `Get-WinEvent` / `Get-NetTCPConnection` / 证书存储 / 注册表写入。\n2. **.NET 与 COM** —— `[System.Guid]::NewGuid()`、`New-Object -ComObject`、任何 `[类型]::方法()` 调用。\n3. **对象管道** —— 需要 `Select-Object Id,WS` 这种结构化字段筛选，而不是文本切割时。\n4. **提权操作** —— 但注意：**这类应该交给人执行**。Git Bash 没有 `sudo`，唯一提权路径是 `Start-Process -Verb RunAs`，它会弹 UAC，agent 无法点击，命令就一直挂着。需要管理员权限的步骤，写进说明让人来做，不要让 agent 去试。\n\n切过去的正确写法是**单条命令**，不是切换会话：\n\n```bash\n# 在 Git Bash 里调一条 PowerShell，用完即回\npowershell -NoProfile -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; (Get-Service wuauserv).Status'\n```\n\n外层务必单引号（防 bash 展开 `$_`、`$null`），UTF-8 前缀对 PS 5.1 必需——细节见 `windows-shell` skill 规则 1。\n\n## 反模式\n\n| 别这样 | 该这样 |\n|------|------|\n| 因为「Windows 就该用 PowerShell」而默认 PowerShell | 默认 Git Bash，只在四类边界处单条切过去 |\n| 为了性能把 Windows 盘上的项目改用 WSL 操作 | 要么整个搬进 ext4，要么留在 Git Bash。别跨 `/mnt/*` |\n| 用小 demo 验证「WSL 访问 `/mnt` 快不快」 | 惩罚随规模放大，小项目试不出来 |\n| 让 agent 尝试提权 | UAC 弹窗会挂死，写进说明让人做 |\n| 遇到报错先怀疑编码 | 先分清：乱码 → 编码问题；语法错/找不到文件 → 参数被改写 |\n| 整个会话切到 PowerShell 或 WSL | 单条命令切换，主线留在 Git Bash |\n\n## 一句话总结\n\n**Git Bash 做主力，PowerShell 管 Windows 系统层面，WSL 只在项目能整个住进 ext4 时才值得。** 三者是分工，不是替代——而分工的默认值应该是 Git Bash。\n\nFile v5.3.0:references/wsl.md\n\n# WSL：值不值得上，以及必知陷阱\n\n考虑把项目搬进 WSL、或已在 WSL 中遇到问题时读本文。\n\n## 什么时候才值得上 WSL\n\nWSL 的优势只有一个来源：**ext4 原生文件系统**。而它成立的前提是**项目文件真的放在 ext4 里**。\n\n| 操作 | ext4（WSL 原生） | NTFS（Windows 原生） | `/mnt/*`（WSL 访问 Windows 盘） |\n|------|------|------|------|\n| tsc 类型检查 | 1.00x | 1.52x | **4.93x** |\n| vitest | 1.00x | 2.36x | **9.69x** |\n| 3000 个小文件增删查 | 1.00x | 8.96x | **54.2x** |\n\n**判定规则：**\n\n- 项目在 `C:\\` / `D:\\` 上 → **不要用 WSL 操作它**。`/mnt/*` 走 9p 协议逐文件跨界，比纯 Windows 还慢 4–6 倍，而且惩罚随项目规模线性放大（文件数 ×3.5，惩罚 ×2）。小 demo 上试不出来，真项目上卡死。\n- 项目能整个搬进 WSL 的 `~/` 且构建密集 → 值得，编译测试全项最快。\n- 只是想跑 `make`、`gcc`、`rsync` → 值得，但记得项目也要在 ext4。\n- 其它情况 → 留在 Git Bash。\n\n**用 WSL 时必须知道的两件事：**\n\n```bash\n# 1) 不要用 wsl.exe -- bash -c '<脚本>' 传复杂脚本\n#    wsl.exe 会用 WSL 登录环境预展开变量，脚本内定义的变量被吞成空，且退出码仍为 0\nwsl.exe -d Ubuntu -- bash -c 'i=3; echo \"$((i+1))\"'   # → 1（错误数字，无报错）\n\n# 正确：走 stdin\nwsl.exe -d Ubuntu -- bash -s <<'EOF'\ni=3; echo \"$((i+1))\"                                   # → 4\nEOF\n\n# 2) 命令先落盘再取退出码，别指望行内 echo\n#    进度条的回车符经 wsl.exe 回传时会互相覆盖，echo $? 整行可能消失\nwsl.exe -d Ubuntu -- bash -s <<'EOF'\nnpx vitest run > /tmp/t.log 2>&1; echo \"EXIT=$?\"; tail -6 /tmp/t.log\nEOF\n```\n\n另外：**git worktree 在 WSL 里完全不可用**——`.git` 文件里存的是 `D:/...` 盘符路径，Linux 的 git 解析不了，直接 fatal。\n\nFile v5.3.0:CHANGELOG.md\n\n# windows-shell 更新日志\n\n版本号与 `SKILL.md` frontmatter 的 `version` 严格一致，由测试看守；\n发布脚本按版本号从本文件提取对应段落作为 changelog。\n\n## 5.3.0\n\n补两条，否掉一条。候选来自 agent 实测自报的「规范没写、只能靠自有知识现推」，\n再用 TokenHub 多模型探针筛出其中模型真不会的（每格 5 次采样，共 240 次调用）。\n\n**新增 1：`PIPESTATUS` 会被下一条命令重置，包括赋值语句本身。**\n\n    cmd | tail -1; a=${PIPESTATUS[0]}; b=${PIPESTATUS[1]}   # ✗ b 恒为 0\n    cmd | tail -1; st=(\"${PIPESTATUS[@]}\")                  # ✓ 紧邻、一次取完\n\n实测 `(exit 7) | tail -1`：紧邻读得 7，中间隔一条命令再读得 0，先赋值再读第二个也得 0。\n原规范只写了「用 ${PIPESTATUS[0]}」，没说它会失效——三个 agent 都在这上面栽过。\nTokenHub 裸问命中率 40%，加规则后 deepseek 两个模型由 4/5、2/5 拉满到 5/5。\n\n**新增 2（辟谣条目）：中文写在 `-Command '...'` 参数里是安全的，不需要 BOM。**\n\n    powershell -NoProfile -Command '$s=\"中文测试\"; Write-Output $s.Length'   # → 4，正确\n\n要 BOM 的只有**脚本文件**（见 5.2.0），命令行参数走的是另一条路径。这条是反向陷阱：\n实测中有两个 agent 因为担心参数被 ANSI 吃掉，绕道去写带 BOM 的 .ps1，白花两条命令。\nTokenHub 裸问只有 40% 答对——六成情况下模型会误以为会坏。\n\n**否掉：编码判定方法（`od` 看字节区分 GBK/UTF-8）。**\n\n四个 agent 点名「规范没写这个」，但 TokenHub 三模型裸问 **15/15 全对**，两轮复测一致。\n它们不是不知道，是不确定该不该做这一步。写进去纯属浪费篇幅，故不收。\n\n这条同时给出一个方法学结论：**agent 自报的 spec_gaps 不能直接采信**。四条候选里，\n一条被证伪（中文传 -Command 根本不会坏，是 agent 误判）、一条被证明模型早就会\n（od 判编码）、只有两条真该写。全部采信会白白撑大主文件。\n\n**一个需要警惕的信号**：主文件已达 8716 字节，逼近测试守卫的 9000 上限。该上限的依据\n是实测的成本曲线（1.9KB 反弹到 1.01x、6.4KB 最优 0.87x、18KB 是 1.43x），现在已超出\n验证过的最优区间。下次再加内容前应先重测成本，不要直接抬高守卫。\n\n**已知局限**：minimax-m3 在 PIPESTATUS 这条上给了规范仍是 0/5，中文 -Command 那条也只\n到 2/5。另两个模型均为 5/5，故判断为该模型在细节题上的固有弱项，未为其调整措辞。\n\n## 5.2.0\n\n新增一条静默失败陷阱，来自对 2644 个历史会话文件的挖掘。\n\n**含中文的 `.ps1` 脚本必须存成 UTF-8 with BOM。** PS 5.1 读脚本时没有 BOM 就按\nANSI/GBK 解析，中文字面量被拆错，且多数情况**不报错**：\n\n    同一段 $s = \"腾讯\"，只差 BOM：\n      PS 5.1 无 BOM  →  $s.Length = 3   ✗\n      PS 5.1 有 BOM  →  $s.Length = 2   ✓\n      pwsh 7 无 BOM  →  $s.Length = 2   ✓（默认按 UTF-8 读脚本）\n\n最阴险的是 `Write-Output $s` **打印出来是对的**——脚本按 GBK 误读、输出时又按 GBK\n编码，两次错误相互抵消，字节兜一圈还原了。但凡取长度、截取、正则、比较、哈希的地方\n全错。连 `$s -eq \"腾讯\"` 都返回 True，因为字面量和变量被同样地误读。\n\n三条独立证据：\n- 历史会话中 65 次 PowerShell ParserError，形如 `Unexpected token '鑵捐','鑵捐寰簯'`\n  ——那是误读的字节恰好构成非法 token 的少数情况\n- 极简版对照实验中，两个 agent 各自独立点名「中文写进 .ps1 需 BOM，规范没写」\n- 本次实测复现（见上表）\n\n它与规则 1（参数被改写）、规则 3（读无 BOM UTF-8 算错行数）同属一族：结果错、不报错、\n退出码 0。`[Console]::OutputEncoding` 前缀救不了它——那只管输出，这是读入。\n\n挖掘方法与其它发现：扫描 2644 个历史会话文件（排除本次会话），只统计 Bash/PowerShell\n执行结果中的错误。分布为路径问题 668、编码乱码 579、git 行尾 320、权限 107、\n文件占用 86、命令不存在 76、PS 语法 65、端口占用 38。其中 git 行尾全部是\n`CRLF will be replaced by LF` 警告、不阻断命令，且已被 `core.autocrlf input` 覆盖，\n未作改动。\n\n一个反直觉的观察：**MSYS2 参数改写在历史日志里只有 13 次**，远低于它在受控实验中的\n危害程度（唯一 100% 分离的指标）。原因正是它的静默性——不留错误信息，因此在日志里\n几乎不可见。**日志频次不能用来给陷阱排优先级。**\n\n## 5.1.0\n\n新增一条静默失败陷阱，来自一次「能不能砍得更狠」的对照实验。\n\n**PS 5.1 读无 BOM 的 UTF-8 文件，不显式写 `-Encoding UTF8` 会静默算错行数。**\n实测：一个 3 行的 UTF-8 文件，某行末尾字节为 `a1 8c 0a`，PS 按 GBK 把 `8c` 当作\n双字节前导、吞掉紧随的换行，`Get-Content` 返回 **2 行**，而 `$?` 仍是 `True`。\n这不是「可能乱码」那种显眼的错，是结果错但不报错——性质与规则 1 的参数改写完全相同。\n\n原表格里虽有「UTF-8 → `-Encoding UTF8`」一行，但那是当作普通对照写的，读者会以为\n不加只是可能乱码。现升格为显式警告，并在开头的判别表中增设**「静默失败」**一类：\n没报错但结果就是不对（参数变了值、行数少一行）→ 必须交叉验证。\n\n发现过程：为回答「规范还能不能更省」，做了一版 1.9KB 的极简规范（只保留实测中模型\n真正做错的两条）做对照。结果是**砍过头会反弹**：\n\n| 规范 | 命令数 | 总 token（vs 无规范） |\n|------|------|------|\n| 无 | 19.2 | 1.00x |\n| 18 KB 全量 | 15.8 | 1.43x |\n| **6.4 KB 按需（本版基线）** | **11.2** | **0.87x** |\n| 1.9 KB 极简 | 17.5 | 1.01x |\n\n砍掉 4.5KB 省下的阅读量，被多出来的 6.3 条试错命令吃光还倒亏。四个 agent 共列出\n23 条「规范没写、只能靠自有知识补」的缺口——编码判定方法、venv/pytest 具体命令、\nPython 转码写法各被点名 3–4 次。模型确实「会」，但每次现推都要花命令。\n\n结论：**6.4KB 附近就是这套规范的成本最优点**，再砍会反弹。而极简版意外撞出的这条\n静默失败，恰恰证明了「模型自己会」的那些条目不能省——g4 就是栽在被我砍掉的那一行上。\n\n## 5.0.0\n\n结构性变更：改为**按需展开**，并把 `windows-shell-routing` 合并进来。\n\n起因是一组 A/B 实测。四臂各跑 4 次同一个 Windows 任务（16 次运行），结论有两条：\n\n- **skill 的作用是精确的，不是普遍的。** 16 次里唯一 100% 分离的指标是「参数被静默改写」\n  这一步——无 skill 组 0/4 一次通过，读了规范的三组 12/12 全部一次通过。其余步骤靠常识\n  也能过，测不出差别。\n- **篇幅不等于价值。** 只读 10KB routing 的一组，总 token 是无 skill 组的 1.09 倍；\n  只读 18KB windows-shell 的一组是 1.43 倍、耗时 1.31 倍——而两组在那个关键步骤上\n  效果完全相同。多出来的 8KB 没有兑现任何行为差异。\n\n所以把一次性全量加载改成按需加载：\n\n- `SKILL.md` 缩到 138 行 / 5.8KB，只保留实测中真正拉开差距的内容：两类问题的判别、\n  shell 选型速查、五条高频规则、一次性环境配置，以及一张「遇到什么读哪个」的索引表。\n- 细节移入 `references/`（25KB，5 个文件）：`encoding.md`、`msys2.md`、\n  `shell-routing.md`、`gitbash-pitfalls.md`、`wsl.md`。规则原文一字未改，只是换了位置。\n- **默认加载量降到原来的 20%**（28.3KB → 5.8KB），完整信息量不减。\n\n合并 `windows-shell-routing`：该技能的全部内容进入 `references/shell-routing.md`、\n`wsl.md`、`gitbash-pitfalls.md`，选型速查表上浮到主文件第二节。之所以能合并，正是因为\n有了按需加载——此前拒绝合并的理由是「两者相加 527 行太长」，那个理由现在不成立了。\n原 slug 走 ClawHub 重定向。\n\n测试相应增加渐进式披露的守卫：主文件体积上限、references 链接必须可解析、不得有孤儿\n文件、以及七个「逃生开关」必须存在于 bundle 中的某处（它们是实测中真正改变了 agent\n行为的部分）。\n\n**发布前做了效果验证，并据此回填了两条。** 首版拆分后重跑同一任务，发现第 1 步\n（GBK 遗留文件转码）的一次通过率从 4/4 掉到 1/4——四个 agent 都正确判出了 GBK，却有\n三个先去试 `iconv`，撞上「Git Bash 没有 iconv」；那条提示被我移进了 references，\n主文件只剩一个指针。同时有三个 agent 点名想查「PS 5.1 怎么写无 BOM 的 UTF-8」，\n主文件只警告了陷阱、没给配方。\n\n于是把这两条回填主文件（新增第 4 条「Git Bash 少几个你以为有的工具」，并在第 3 条\n补上 `WriteAllText` + `UTF8Encoding($false)` 的写法），主文件从 5.8KB 到 6.4KB。\n重跑验证：第 1 步回到 4/4，命令数 11.2（六臂最低），总 token 相对无规范 0.87x\n——**是所有方案里唯一比不用规范还便宜的**。相对拆分前的 18KB 全量版：\ntoken 0.60x、耗时 0.54x、命令 0.71x。\n\n跨模型交叉验证（经腾讯 TokenHub 调 deepseek-v3.2 / v4-flash / minimax-m3 三个模型，\n7 道知识探针，**每格采样 5 次**共 210 次调用）：\n\n| 考点 | 裸问 | 给规范 | 判定 |\n|------|------|------|------|\n| Git Bash 有无 `iconv` | **20%** | 100% | **★ 唯一真缺口，+80pt** |\n| 参数被改写的现象 | 93% | 100% | 模型本就会 |\n| `MSYS_NO_PATHCONV` 绕法 | **100%** | 100% | 模型本就会 |\n| PS 5.1 写无 BOM | 93% | 100% | 模型本就会 |\n| 读 GBK 文件 / `>` 重定向编码 | 100% | 100% | 模型本就会 |\n| 读无 BOM UTF-8 静默错 | 80% | 100% | 模型本就会 |\n\n> **更正**：本文件早先的版本称「`MSYS_NO_PATHCONV` 五个模型十次裸问没有一次答对」。\n> 那是错的。当时的探针把这道题写成了承接上一题的追问（「承上，如果…」），而模型\n> 拿不到上文——测出的是**题目歧义**，不是知识缺口。把前提补进题干、每格采样 5 次\n> 之后，裸问命中率是 **15/15（100%）**。\n\n所以规范的价值并不像先前推断的那样来自「补上模型不知道的冷门开关」——七道题里只有\n`iconv` 一条是真盲区。真正的机制是另一个：模型**知道**，但不会当场想起来并照做。\nG 极简版实验从反面证实了这点：砍掉那些「模型自己会」的条目后，命令数从 11.2 反弹到\n17.5，四个 agent 列出 23 条「只能靠自有知识现推」的缺口。**规范省的是现推的过程，\n不是补知识。**\n\n另一个方法学教训：`temperature=0` 并不确定性。同一 prompt 连问三次，内容指纹三次\n全不同（耗时均为 5s 量级，排除了服务端缓存）。此前每格只采样 1 次的做法不足以支撑\n结论，本次已全部改为 5 次。\n\n**一个诚实的限制**：两轮共 8 次运行中，agent 读取 references 的次数是 **0**，\n全部自评「主文件够用」。所以当前成立的其实是「主文件压缩到够用 + 附录供人查阅」，\n而不是 agent 会自己按指针去取。今后往 references 放内容需按此前提判断：\n凡是 agent 真正需要的，必须留在主文件里。\n\n## 4.4.0\n\n新增 MSYS2 参数改写规则，并修正三处经复测证伪的旧结论。稳定性结论均为 12 次采样，\n不再是单次观察。\n\n修正：\n\n- **pwsh 7 不再标注「输出可能乱码（实测不稳定）」**。实测 12/12 稳定 UTF-8。\n  UTF-8 前缀只对 PS 5.1 必需；外部程序（node/python）的输出穿过 PowerShell 不会被改，\n  两侧都不受影响。规则 1 改为一张按「中文来源 × 是否加前缀」划分的实测表。\n- **`reg query` 移出编码禁用表**。它的失败是 MSYS2 把注册表路径当 Unix 路径改写\n  （报「无效语法」而非乱码），加 `MSYS_NO_PATHCONV=1` 后原命令即可正常工作，与编码无关。\n  规则 3 因此拆为 A 类（真编码问题：wmic/systeminfo/ipconfig/netstat/tasklist/net user）\n  与 B 类（参数改写：reg query/findstr/schtasks），两类解法完全不同。\n- **规则 4 补上前提**。配好用户级 `PYTHONUTF8` 后裸 `python -c` 已经正常；\n  `-X utf8` 的价值在于不依赖环境（CI、容器、别人的机器），而非「不加必乱码」。\n  附反证：清空该变量后 `getpreferredencoding` 立刻退回 `cp936`。\n\n新增（原规则 6/7/8 顺延为 8/9/10）：\n\n- **规则 6：MSYS2 会改写以 `/` 开头的参数**。`/api/v1/users` 被改写成\n  `D:/Program Files/Git/api/v1/users`，`/S /C` 变成 `S:/ C:/`，Docker 的 `-v` 参数被吃掉。\n  最坏的是它**静默生效**——不报错、退出码正常、参数已经变了。给出\n  `MSYS_NO_PATHCONV` / `MSYS2_ARG_CONV_EXCL` / 双斜杠三种解法，并说明为什么不能全局导出\n  （会让 `/c/Users/...` 这类本该转换的参数也不转）。\n- **规则 7：`ln -s` 默认产出普通文件副本**，影响 pnpm workspace / npm link；\n  `MSYS=winsymlinks:nativestrict` 可修，附开发者模式检查命令。\n\n另新增开头的「两类问题，别混为一谈」判别小节（乱码 → 编码；语法错/找不到文件 → 参数改写），\n并在「不需要包装的工具」白名单下注明：输出编码干净 ≠ 没坑。\n\n## 4.3.0\n\n修正「一键配置」那行：原文写的 `npx win-encoding-fix install --setup-env` 从来没能工作过\n——该包从未发布到 npm，且 npx 解析的是包名而不是 bin 名。改为从仓库执行\n`node bin/cli.js setup-env`。仓库已重构为 skill-factory（Skill 工厂）多技能布局，\n本技能现位于 `skills/windows-shell/`；ClawHub slug、安装目录名与 frontmatter 的 name\n仍然都是 `windows-shell`，未发生变化。bundle 内容现为 SKILL.md + CHANGELOG.md。\n编码规则正文无改动。\n\n## 4.2.0\n\n修复 setup-env 的 Windows 用户级环境变量根本没设成功的 bug（嵌套双引号被 cmd.exe 吞掉）；\nSKILL.md 补充 GBK 遗留文件读取、UTF-8 BOM、Out-File 默认 UTF-16、stdin/InputEncoding、\n原始字节工具等编码陷阱；CLI 支持多盘 OpenClaw、失败时退出非零、参数解析健壮化；\n测试全程隔离 HOME 并大幅提升覆盖。\n\nFile v5.3.0:skill-card.md\n\n## Description:\n\nWindows Shell gives agents practical command-line guidance for Windows 10/11 environments, including shell selection, Git Bash defaults, GBK/UTF-8 encoding, BOM handling, MSYS2 path rewriting, PowerShell and WSL routing, Python/Node.js execution, Git configuration, and code-generation practices.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chenmo0414](https://clawhub.ai/user/chenmo0414)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and coding agents use this skill when running command-line tasks on Windows with MSYS2/Git Bash, PowerShell, or WSL. It helps choose the right shell and avoid common silent failures caused by encoding defaults, path conversion, environment persistence, and cross-shell behavior.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The security review flags an unpinned external setup command.\n\nMitigation: Inspect a pinned version of the referenced setup repository before running the one-click setup command, or apply the documented configuration steps manually.\n\nRisk: The skill recommends persistent user-level environment, shell profile, and global Git configuration changes.\n\nMitigation: Review each persistent change before applying it and limit changes to the specific Windows account or project workflow that needs them.\n\n## Reference(s):\n\n- [windows-shell Skill Page](https://clawhub.ai/chenmo0414/skills/windows-shell)\n- [Publisher Profile](https://clawhub.ai/user/chenmo0414)\n- [Project Homepage](https://github.com/Chenmo0414/win-encoding-fix)\n- [encoding.md](references/encoding.md)\n- [gitbash-pitfalls.md](references/gitbash-pitfalls.md)\n- [msys2.md](references/msys2.md)\n- [shell-routing.md](references/shell-routing.md)\n- [wsl.md](references/wsl.md)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Shell commands, Configuration]\n\n**Output Format:** [Markdown with inline shell, PowerShell, Python, and configuration examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Guidance is organized as a quick routing table with optional reference files for deeper Windows shell, encoding, MSYS2, Git Bash, and WSL details.]\n\n## Skill Version(s):\n\n5.3.0 (source: server release evidence, SKILL.md frontmatter, CHANGELOG.md)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v5.1.0: 9 files, 24755 bytes\n\nFiles: CHANGELOG.md (8856b), references/encoding.md (12160b), references/gitbash-pitfalls.md (2525b), references/msys2.md (3455b), references/shell-routing.md (5061b), references/wsl.md (1929b), skill-card.md (2423b), SKILL.md (7085b), _meta.json (132b)\n\nFile v5.1.0:SKILL.md\n\n---\nname: windows-shell\nversion: 5.1.0\ndescription: \"Windows 命令行工作规范：先选对 shell（默认 Git Bash），再避开编码与 MSYS2 参数改写两类陷阱。覆盖 GBK/UTF-8、BOM、MSYS2 路径转换、PowerShell/pwsh、WSL 判定、Python/Node.js、Git 配置与代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。细节按需读 references/。\"\nlicense: MIT\nmetadata:\n  openclaw:\n    emoji: \"🪟\"\n    os: [windows]\n    homepage: \"https://github.com/Chenmo0414/win-encoding-fix\"\n---\n\n# Windows 命令行工作规范\n\n用户系统：Windows 10/11（代码页 GBK/936），终端：MSYS2/Git Bash。\n\n**本文件是速查与路由表。** 每条规则下面标了「细读」，只在真正遇到那类问题时再去读对应的\n`references/` 文件——不要一次性全部读完。\n\n## 一、先分清是哪一类问题\n\n在 Git Bash 里执行命令出问题，绝大多数是这两类之一。**先判类，再套解法**，两类的解法完全不通用：\n\n| 症状 | 类别 | 第一反应 |\n|------|------|------|\n| 输出乱码（`涓枃`、`M-DM-c`、方块字） | **编码** | 让源头输出 UTF-8 |\n| 没报错但**结果就是不对**（参数变了值、行数少一行） | **静默失败** | 见第 1、3 条，必须交叉验证 |\n| 报「无效语法 / invalid / 找不到文件」，或参数悄悄变了值 | **MSYS2 参数改写** | `MSYS_NO_PATHCONV=1` |\n\n拿编码的解法去治参数改写，怎么加前缀都不好使——这是最常见的误诊。\n\n## 二、选对 shell（默认 Git Bash）\n\n| 你要做的事 | 用哪个 |\n|------|------|\n| npm / node / npx / tsc / vitest / python / pip / pytest / git / ssh | **Git Bash** |\n| Windows 服务、注册表、事件日志、计划任务、证书、.NET/COM、对象管道 | **PowerShell**（单条命令切过去，主线不搬家） |\n| 跑 Makefile、需要 gcc/rsync，或重 I/O 构建且项目能整个搬进 ext4 | **WSL** |\n| 需要管理员权限 | **交给人做**——UAC 弹窗 agent 点不了，命令会一直挂着 |\n\n项目文件在 `C:\\`/`D:\\` 上时，**不要用 WSL 去操作它**：跨 `/mnt/*` 比纯 Windows 还慢 4–6 倍，\n且惩罚随项目规模线性放大。\n\n> 细读：判断依据与完整决策表 → [shell-routing.md](references/shell-routing.md)；\n> WSL 值不值得上 → [wsl.md](references/wsl.md)\n\n## 三、必须知道的六条\n\n下面六条是实测中真正拉开差距的。其余规则都在 `references/`。\n\n### 1. 以 `/` 开头的参数会被静默改写\n\nGit Bash 把它当 Unix 路径转成 Windows 路径再传给原生程序。**不报错、退出码 0、参数已经变了**：\n\n```bash\nnode app.js /api/v1/users          # 程序实收 D:/Program Files/Git/api/v1/users\ndocker run -v /app:/app ...        # -v 后面被吃掉\nreg query \"HKCU\\Environment\"       # 错误: 无效语法。\n```\n\n```bash\nMSYS_NO_PATHCONV=1 node app.js /api/v1/users    # 单条前置，不要全局导出\n```\n\n全局导出会让 `/c/Users/...` 这类本该转换的参数也不转。\n\n> 细读：另两种绕法、符号链接退化 → [msys2.md](references/msys2.md)\n\n### 2. PowerShell 5.1 输出中文必须加前缀\n\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; 你的命令'\n```\n\n外层用**单引号**（防 bash 展开 `$_`、`$null`）。pwsh 7 不需要这个前缀，加了也无害。\n外部程序（node/python）自己写的 UTF-8 穿过 PowerShell 不会被改。\n\n### 3. 读遗留文件前先验编码，别硬套 UTF-8\n\n对一个真正的 GBK/936 文件强加 `-Encoding UTF8` 会读出乱码。先看字节再决定：\n\n```bash\nod -c legacy.txt | head -2        # 或 xxd；Git Bash 没有 hexdump\n```\n\n| 文件真实编码 | PS 5.1 | pwsh 7 |\n|------|------|------|\n| UTF-8 | `-Encoding UTF8`（**必须显式写**） | 默认即可 |\n| GBK/936 | `-Encoding Default` | `[System.Text.Encoding]::GetEncoding(936)` |\n\n**PS 5.1 读无 BOM 的 UTF-8 不加 `-Encoding UTF8` 会静默出错**——不是乱码那么显眼，\n而是行数直接算错、退出码仍为 0。实测：一个 3 行的 UTF-8 文件，某行末尾字节是\n`a1 8c 0a`，PS 按 GBK 把 `8c` 当双字节前导、吞掉紧随的换行，`Get-Content` 返回\n**2 行**且 `$?` 为 `True`。性质与上面第 1 条的参数改写相同：**结果错、不报错**。\n所以 **PS 5.1 读任何文本文件都显式指定 `-Encoding`**，别赌默认值。\n\n**写出去也有坑**：PS 5.1 的 `-Encoding UTF8` 会带 BOM，`>` 重定向默认写 UTF-16。要无 BOM 的 UTF-8：\n\n```powershell\n[System.IO.File]::WriteAllText(\"out.txt\", $s, (New-Object System.Text.UTF8Encoding($false)))\n```\n\n> 细读：更多 BOM/重定向陷阱、`$OutputEncoding`、传统 CMD 工具替代表\n> → [encoding.md](references/encoding.md)\n\n### 4. Git Bash 少几个你以为有的工具\n\n`iconv`、`jq`、`make`、`gcc`、`rsync`、`hexdump` **都没有**。转码不要指望 `iconv`，\n验字节用 `od -c`，其余场景改用 Python 或 Node 顶上；真需要完整 GNU 工具链就上 WSL。\n\n```bash\npython -c \"import io;io.open('out.txt','w',encoding='utf-8').write(io.open('in.txt',encoding='gbk').read())\"\n```\n\n### 5. 生成代码时显式写编码，不依赖环境\n\n```python\nopen('data.txt', encoding='utf-8')          # 裸 open() 在 Windows 上默认 cp936\n```\n\n```bash\npython -X utf8 -c \"...\"                      # 单行命令，不假设 PYTHONUTF8 已生效\n```\n\n环境变量会失效，代码里的显式声明不会。\n\n### 6. venv 直接调解释器，绕开 activate\n\n```bash\n./.venv/Scripts/python.exe -m pytest         # source activate 会拼出正反斜杠混拼的畸形路径\n```\n\n同理，管道会吞掉上游退出码，要用 `set -o pipefail` 或 `${PIPESTATUS[0]}`。\n\n> 细读：venv、工具集不全、SSH 密钥、符号链接 → [gitbash-pitfalls.md](references/gitbash-pitfalls.md)\n\n## 四、一次性环境配置\n\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8;\n  [Environment]::SetEnvironmentVariable(\"PYTHONUTF8\", \"1\", \"User\");\n  [Environment]::SetEnvironmentVariable(\"PYTHONIOENCODING\", \"utf-8\", \"User\")'\ngit config --global core.quotepath false\ngit config --global core.autocrlf input\n```\n\n写进 `~/.bash_profile` 的变量**非登录 shell 不会加载**（agent 正是这种 shell），\n所以要设成 Windows 用户级环境变量。\n\n> 细读：完整配置与每条的理由 → [encoding.md](references/encoding.md) 的「环境前置条件」\n\n## 五、按需索引\n\n| 遇到什么 | 读哪个 |\n|------|------|\n| 乱码、BOM、UTF-16、GBK 遗留文件、CMD 工具替代 | [encoding.md](references/encoding.md) |\n| 参数被改写、符号链接变成副本 | [msys2.md](references/msys2.md) |\n| 不确定该用哪个 shell、想看实测依据 | [shell-routing.md](references/shell-routing.md) |\n| venv、工具缺失、SSH 密钥、管道退出码 | [gitbash-pitfalls.md](references/gitbash-pitfalls.md) |\n| 要不要上 WSL、`wsl.exe` 变量吞噬 | [wsl.md](references/wsl.md) |\n\nFile v5.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn78ryxatfm99gvwnvgexh8hkx847bk7\",\n  \"slug\": \"windows-shell\",\n  \"version\": \"5.1.0\",\n  \"publishedAt\": 1787155530011\n}\n\nFile v5.1.0:references/encoding.md\n\n# 编码细节（GBK / UTF-8 / BOM）\n\n主文件 `SKILL.md` 只放了最常用的两条。遇到下列任一情况时读本文：\n读写文件出现乱码、需要处理 GBK 遗留文件、需要写无 BOM 的 UTF-8、\nPowerShell 重定向编码不对、管道方向的编码问题、传统 CMD 工具输出乱码。\n\n## 环境自检（开工前可选执行）\n\n判断当前 shell 的编码是否已正确配置：\n\n```bash\npython -c \"import sys; print('utf8_mode=', sys.flags.utf8_mode)\"   # 期望 1；为 0 说明 Python 默认 GBK\necho \"PYTHONUTF8=$PYTHONUTF8\"                                       # 期望 1；为空说明环境变量未加载\n```\n\n**关键认知**：`PYTHONUTF8` 等变量若只写在 `~/.bash_profile`，**非登录 / 非交互 shell 不会加载它**（AI 助手与脚本通常正是这种 shell）。因此：\n\n- 持久生效请配置 **Windows 用户级环境变量**（被所有进程继承，重启终端后生效）；\n- 当前会话内最可靠的做法是**每条命令显式带编码参数**（见下方各规则）。\n\n## 环境前置条件（持久配置，建议一次性执行）\n\n```bash\n# 1) Windows 用户级环境变量 —— 最可靠，所有进程继承（重启终端后生效）\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8;\n  [Environment]::SetEnvironmentVariable(\"PYTHONUTF8\", \"1\", \"User\");\n  [Environment]::SetEnvironmentVariable(\"PYTHONIOENCODING\", \"utf-8\", \"User\")'\n\n# 2) bash 显示相关变量（登录 shell 用），并让 .bashrc 也加载，覆盖非登录交互 shell\ncat >> ~/.bash_profile <<'EOF'\nexport PYTHONUTF8=1\nexport PYTHONIOENCODING=utf-8\nexport LANG=en_US.UTF-8\nexport LESSCHARSET=utf-8\nEOF\ngrep -q 'bash_profile' ~/.bashrc 2>/dev/null || echo '[ -f ~/.bash_profile ] && . ~/.bash_profile' >> ~/.bashrc\n\n# 3) Git 全局配置\ngit config --global core.quotepath false        # 中文文件名正常显示\ngit config --global core.autocrlf input         # 提交 LF，检出保持原样\ngit config --global i18n.commitEncoding utf-8    # commit 消息 UTF-8\ngit config --global i18n.logOutputEncoding utf-8\ngit config --global core.pager \"less -R\"\n```\n\n> 一键配置：在 [skill-factory](https://github.com/Chenmo0414/win-encoding-fix) 仓库里执行 `node bin/cli.js setup-env`\n\n### 规则 1：PowerShell 命令必须加 UTF-8 前缀 + 外层单引号\n\n```bash\n# 标准模板（外层单引号 + UTF-8 前缀）\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; 你的命令'\n```\n\n**两个要点必须同时满足：**\n- `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8` — 不加则中文输出乱码\n- 外层**单引号** — 防止 bash 把 `$_`、`$null` 当作 bash 变量展开\n\n仅当命令中不含 `$` 变量时才可用外层双引号。\n\n**前缀到底什么时候必需**（v4.3.0 实测，各采样 12 次，结果完全稳定）：\n\n| 中文的来源 | PS 5.1 无前缀 | PS 5.1 加前缀 | pwsh 7 无前缀 |\n|------|------|------|------|\n| PowerShell 自己产出（`Write-Output`、cmdlet 结果） | **GBK ×12 → 乱码** | UTF-8 ×12 ✅ | **UTF-8 ×12 ✅** |\n| 外部程序产出（`node -e`、`python` 等） | UTF-8 ×12 ✅ | UTF-8 ×12 ✅ | UTF-8 ×12 ✅ |\n\n- **PS 5.1 必须加前缀**：只要中文由 PowerShell 自己产出，不加就是稳定乱码，没有侥幸。\n- **pwsh 7 不需要前缀**：实测 12/12 稳定 UTF-8。加了无害，脚本要兼容 5.1 时统一加是合理的，但不必因为「怕 pwsh 不稳」而加。\n- **外部程序的输出不受影响**：`node`/`git`/`python` 自己写 UTF-8 到 stdout，穿过 PowerShell 不会被改。所以「PS 包装」只对遵守控制台代码页的 Windows 原生工具才有意义（见规则 3）。\n\n### 规则 2：PowerShell 读写文件 —— `-Encoding` 必须匹配文件真实编码\n\n**读 UTF-8 文件**：PowerShell 5.1 不加 `-Encoding UTF8` 会用 GBK 读取，实测 `中文` → `涓枃`。\n\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Content \"path\\file.txt\" -Encoding UTF8'\n```\n\n**⚠️ 读 GBK 遗留文件（本机最常见）**：反过来，对一个真正的 GBK/936 文件强加 `-Encoding UTF8` 会**读出乱码**。`-Encoding` 的值必须等于文件的真实编码：\n\n| 文件真实编码 | PS 5.1 读法 | pwsh 7 读法 |\n|------|------|------|\n| UTF-8 | `-Encoding UTF8` | 默认即可（或 `-Encoding utf8`） |\n| GBK/936（遗留） | `-Encoding Default` 或不加 | `-Encoding oem` 或 `[System.Text.Encoding]::GetEncoding(936)` |\n\npwsh 7 默认按 UTF-8 读，遇到 GBK 文件反而会 mojibake，此时**必须显式指定 936**。\n\n**写文件的 BOM 陷阱**：PS 5.1 的 `Set-Content -Encoding UTF8` / `Out-File -Encoding UTF8` 会写入 **UTF-8 BOM**（`EF BB BF`），很多工具（旧编译器、某些 JSON 解析器、shell 脚本）会因此报错。要写**无 BOM** UTF-8：\n\n```powershell\n# PS 5.1 无 BOM 写法\n[System.IO.File]::WriteAllText(\"out.txt\", $content, (New-Object System.Text.UTF8Encoding($false)))\n# pwsh 7\nSet-Content out.txt -Value $content -Encoding utf8NoBOM\n```\n\n**输出重定向的编码**：PS 5.1 的 `>` 和 `Out-File` **默认写 UTF-16 LE**，不是 UTF-8。若要把命令输出存成 UTF-8 文件给后续读取，务必显式 `... | Out-File -Encoding utf8 out.txt`（注意上面的 BOM 说明），或捕获字符串后用 .NET 写。\n\n**stdin / 管道方向**：`[Console]::OutputEncoding` 只管 PowerShell **输出**。若要把 UTF-8 内容通过管道**喂进** PowerShell（`echo ... | powershell ...`），还需 `[Console]::InputEncoding = [System.Text.Encoding]::UTF8`；而 PowerShell **管道给下游原生命令**（如 `... | findstr`）用的是 `$OutputEncoding` 变量（默认 ASCII，会丢中文）。能用内联 `-Command` 参数就别走 stdin 管道。\n\n### 规则 3：禁止直接使用传统 CMD 工具和 cmd /c\n\n传统 CMD 工具多数输出 GBK 或 UTF-16，在 UTF-8 终端中乱码。`cmd /c` 同样不可用——`chcp 65001` 无法修复子进程编码（实测 `cmd /c \"chcp 65001 & echo 你好\"` 仍乱码）。\n\n但**并非全都是编码问题**。实测把它们分成了两类，解法完全不同：\n\n**A 类 —— 真·编码问题**（实测输出 GBK 字节，PS 包装可解决）：\n\n| 禁止 | 替代 |\n|------|------|\n| `wmic` | `Get-CimInstance` |\n| `systeminfo` | `Get-ComputerInfo` 或 PS 包装 `systeminfo` |\n| `ipconfig` | `Get-NetIPAddress` / `Get-NetIPConfiguration` |\n| `netstat` | `Get-NetTCPConnection` |\n| `tasklist` | `Get-Process` |\n| `net user` | `Get-LocalUser` |\n| `sc query` | `Get-Service`（英文输出时不乱码，但中文服务名会） |\n| `cmd /c` | **永远不用** |\n\n**B 类 —— 其实是 MSYS2 参数改写，不是编码问题**（实测：加 `MSYS_NO_PATHCONV=1` 后原命令即可正常工作）：\n\n| 命令 | 默认失败表现 | 真实原因 |\n|------|------|------|\n| `reg query \"HKCU\\Environment\"` | `错误: 无效语法。` | 注册表路径被当成 Unix 路径改写 |\n| `findstr 中文 /tmp/x.txt` | `FINDSTR: 无法打开 C:x.txt` | `/tmp/x.txt` 被改写成 `C:x.txt` |\n| `schtasks /query /tn \"\\...\"` | 参数错误 | 同上 |\n\nB 类仍然**建议**换成 `Get-ItemProperty` / `Select-String` / `Get-ScheduledTask`——PowerShell 版本输出更结构化、也不受 MSYS2 影响。但要知道：**它们不是「因为乱码」才被禁的**，误诊会让你在别处用错解法（比如给一个路径被改写的命令拼命加编码前缀，怎么加都不好使）。\n\n在 PowerShell 中包装传统命令**通常**可正确转码：\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; systeminfo | Select-Object -First 5'\n```\n\n> **注意，包装不是万能的**：`[Console]::OutputEncoding` 只对**遵守控制台输出代码页**的工具有效（`systeminfo`、`ipconfig` 等）。对于**输出固定 GBK 字节或原始字节**的工具（部分第三方 CLI、某些日志），包装后仍是乱码——这类需要「先按 936 解码、再转 UTF-8」：`powershell -Command '$s = (& some.exe) ; [Console]::OutputEncoding = [System.Text.Encoding]::UTF8; [System.Text.Encoding]::GetEncoding(936).GetString(...)'`，或在 Node/Python 侧以**字节**捕获再按真实编码解码（见规则 5、规则 9）。\n\n### 规则 4：Python 命令行执行 —— 优先 `-X utf8`，不要假设环境\n\n实测：AI 助手与脚本运行在**非交互 shell**，若 `PYTHONUTF8` 只写在 `~/.bash_profile`，它不会被加载，`sys.flags.utf8_mode` 为 0，`python -c \"print('你好')\"` 直接乱码。\n\n**注意前提**：一旦按上文「环境前置条件」把 `PYTHONUTF8` 配成了 **Windows 用户级环境变量**，裸 `python -c \"print('你好')\"` 就已经正常了（实测 `utf8_mode=1`、`getpreferredencoding=utf-8`）。所以 `-X utf8` 的价值不是「不加就一定乱码」，而是**不依赖环境是否配好**——在别人的机器、CI、容器里同样成立。这也正是它值得默认带上的理由。\n\n反证：把 `PYTHONUTF8` 清空后再测，`getpreferredencoding` 立刻退回 `cp936`。环境配置是会失效的，代码里的显式声明不会。\n\n**最可靠做法 —— 单行命令显式带 `-X utf8`：**\n```bash\npython -X utf8 -c \"print('你好世界')\"\n# 或临时设环境变量\nPYTHONUTF8=1 python script.py\n```\n\n`-X utf8` 同时让 `print()` 输出与 `open()` 默认读写都走 UTF-8，幂等无副作用，已是 UTF-8 环境时加它也不会出错。**生成代码时**仍应显式写 `encoding='utf-8'`（见规则 8），不依赖运行时标志。\n\n### 规则 5：Node.js 子进程调用系统命令\n\nNode.js 自身输出 UTF-8 没问题，但 `execSync`/`exec`/`spawn` 调用传统 CMD 工具时，输出是 GBK，`toString('utf-8')` 会乱码。\n\n**修复**：让子进程通过 PowerShell 输出 UTF-8：\n```javascript\nexecSync('powershell -Command \"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; systeminfo\"').toString('utf-8')\n```\n\n对于**输出原始 GBK 字节、不认控制台代码页**的工具，PowerShell 包装无效，应以字节捕获再手动解码：\n```javascript\nconst { execSync } = require('child_process')\nconst buf = execSync('some-gbk-tool.exe')       // 拿 Buffer，不要直接 toString\nconst text = new TextDecoder('gbk').decode(buf)  // 按真实编码解码\n```\n\n### 规则 8：Python 文件 I/O 必须指定编码\n\n```python\n# 正确 — 显式指定 encoding\nwith open('data.txt', 'r', encoding='utf-8') as f:\n    content = f.read()\n\nwith open('output.txt', 'w', encoding='utf-8') as f:\n    f.write(content)\n\n# 错误 — 裸 open() 在 Windows 上默认 GBK（实测 locale.getpreferredencoding() = cp936）\nwith open('data.txt', 'r') as f:  # 不要这样写\n    content = f.read()\n```\n\n同样适用于 `json.load`/`json.dump`、`csv.reader`、`pathlib.Path.read_text()` 等需要文件对象的场景。\n\nPython subprocess 调用系统命令时也需注意编码：\n```python\nimport subprocess\nresult = subprocess.run(\n    ['powershell', '-Command', '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Process'],\n    capture_output=True, text=True, encoding='utf-8'\n)\n```\n\n### 规则 9：Node.js 文件操作和子进程编码\n\n```javascript\n// 文件读写 — 显式指定 utf-8\nfs.readFileSync('data.txt', 'utf-8')\nfs.writeFileSync('output.txt', content, 'utf-8')\n\n// 子进程调用 Windows 原生命令 — 通过 PowerShell 包装\nconst { execSync } = require('child_process')\nconst output = execSync(\n  'powershell -Command \"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Service\"'\n).toString('utf-8')\n```\n\n### 规则 10：Git 中文支持\n\n环境已配置 `core.quotepath=false`，中文文件名在 `git status`/`git diff` 中正常显示。\n\n如果发现中文文件名仍显示为 `\\346\\265\\213\\350\\257\\225` 形式，执行：\n```bash\ngit config --global core.quotepath false\n```\n\n## 格式化技巧\n\n- 宽表格加 `| Out-String -Width 200` 防截断\n- `Format-Table -AutoSize` 自适应列宽\n- `Format-List` 展示详细单条记录\n- `Select-Object` 控制返回字段数量\n\nFile v5.1.0:references/gitbash-pitfalls.md\n\n# Git Bash 的五个坑\n\n在 Git Bash 下遇到非编码类异常时读本文：参数被改写、符号链接失效、\nvenv 激活路径异常、工具缺失、SSH 密钥不通用、管道吞退出码。\n\n## Git Bash 的五个坑\n\n选了 Git Bash，这五个必须知道，否则会以为是代码的问题。\n\n### 坑 1：以 `/` 开头的参数会被改写（静默）\n\nMSYS2 把它们当 Unix 路径转成 Windows 路径再传给程序。**不报错、退出码正常、参数已经变了**：\n\n```bash\nnode app.js /api/v1/users     # 程序收到 D:/Program Files/Git/api/v1/users\nprog /S /C                    # → S:/ C:/\ndocker run -v /app:/app ...   # -v 后面被吃掉\n```\n\n```bash\n# 解法：单条命令前置，别全局导出\nMSYS_NO_PATHCONV=1 node app.js /api/v1/users\n```\n\n全局导出会让 `/c/Users/...` 这类你确实希望被转换的参数也不转了。\n\n### 坑 2：`ln -s` 默认产出的是副本\n\n```bash\nln -s t.txt l.txt && ls -l l.txt      # -rw-r--r--  ← 是副本，不是链接\nexport MSYS=winsymlinks:nativestrict  # 修复后 → lrwxrwxrwx\n```\n\n**pnpm workspace、npm link、monorepo 本地依赖都依赖真符号链接**，退化成副本会表现为「改了源码不生效」。需先启用 Windows 开发者模式。\n\n### 坑 3：venv 的 `activate` 会拼出畸形路径\n\n```bash\nsource .venv/Scripts/activate    # VIRTUAL_ENV 丢盘符，路径变成 /d/proj/\\proj\\.venv/Scripts/python\n```\n\n虽然仍能解析，但不可靠。**直接调解释器，绕开 activate**：\n\n```bash\n./.venv/Scripts/python.exe -m pytest\n./.venv/Scripts/python.exe -m pip install -r requirements.txt\n```\n\n### 坑 4：工具集不全\n\n`jq`、`make`、`gcc`、`rsync` 都**没有**。跑 Makefile 的项目直接卡住——那种情况上 WSL，不要试图在 Git Bash 里凑。\n\n### 坑 5：SSH 密钥位置与 WSL 不通用\n\nGit Bash 与 Windows 共用 `C:\\Users\\你\\.ssh`，**WSL 用的是独立的 `/root/.ssh`**。在 Windows 配好的 SSH，到 WSL 里等于从零开始。\n\n而且 `/mnt/*` 上的文件在 WSL 眼里权限是 `777`，OpenSSH 会判定 `bad permissions` 直接忽略该密钥。要在 WSL 里用 ssh，密钥必须复制到 ext4 并 `chmod 600`。Git Bash 没有这个问题（它走 Windows ACL，不看 POSIX 权限位）。\n\n### 附：管道会吞掉退出码\n\n这不是 Git Bash 特有，但 agent 最容易在这里误判成功：\n\n```bash\nnpm install ... | tail -25      # $? 是 tail 的，不是 npm 的\nset -o pipefail                 # 或用 ${PIPESTATUS[0]}\n```\n\nFile v5.1.0:references/msys2.md\n\n# MSYS2 参数改写与符号链接\n\n主文件已给出 `MSYS_NO_PATHCONV=1` 这一条速查。需要完整解释、\n其它两种绕法、或遇到符号链接/工具缺失问题时读本文。\n\n### 规则 6：MSYS2 会改写以 `/` 开头的参数\n\nGit Bash（MSYS2）在把参数交给 **非 MSYS2 程序**（即所有 Windows 原生 .exe）之前，会把看起来像 Unix 路径的参数自动转换成 Windows 路径。这是 MSYS2 的设计，不是 bug——但它**静默生效**，不报错、退出码正常，参数已经变了。\n\n```bash\nnode app.js /api/v1/users\n# 程序实际收到：D:/Program Files/Git/api/v1/users   ← 前面被拼上了 Git 安装目录\n\nprog /S /C                  # → 变成  S:/ C:/\ndocker run -v /app:/app ... # → -v 后面的参数被破坏\nreg query \"HKCU\\Environment\"   # → 错误: 无效语法。\nfindstr 中文 /tmp/x.txt        # → FINDSTR: 无法打开 C:x.txt\n```\n\n**什么时候会中招**：参数以 `/` 开头，且接收方是 Windows 原生程序。典型场景——REST 路径、Docker 卷映射、Windows 风格开关（`/S` `/C` `/query`）、注册表路径、传给 `.exe` 的 Unix 路径。\n\n**三种解法**（均实测有效）：\n\n```bash\n# A. 单条命令临时关闭（推荐，作用域最小）\nMSYS_NO_PATHCONV=1 reg query \"HKCU\\Environment\" /v PYTHONUTF8\nMSYS_NO_PATHCONV=1 node app.js /api/v1/users\n\n# B. 按参数排除\nMSYS2_ARG_CONV_EXCL='*' node app.js /api/v1/users\n\n# C. 双斜杠转义（只想保护单个参数时）\nnode app.js //api/v1/users\n```\n\n**不要全局导出 `MSYS_NO_PATHCONV=1`**：关掉转换后，`/c/Users/...` 这类你确实希望被转成 `C:\\Users\\...` 的参数也不再转换，会引入另一批问题。按需在单条命令前加。\n\n> 与编码问题的区别：编码问题表现为**乱码**，参数改写表现为**语法错/找不到文件/行为不对但不报错**。诊断时先看报错形态，别拿编码的解法去治路径的病。\n\n### 规则 7：Git Bash 的 `ln -s` 默认产出的是副本\n\n```bash\nln -s t.txt l.txt && ls -l l.txt\n# 默认：  -rw-r--r--  ← 普通文件副本，不是链接\n```\n\n对普通脚本无所谓，但 **pnpm workspace、npm link、monorepo 的本地依赖都依赖真符号链接**，退化成副本会导致改了源码却不生效、或磁盘占用异常。\n\n```bash\n# 修复：产出真正的符号链接（lrwxrwxrwx）\nexport MSYS=winsymlinks:nativestrict\nln -s t.txt l.txt && ls -l l.txt      # → lrwxrwxrwx ... l.txt -> t.txt\n```\n\nWindows 10/11 需先启用**开发者模式**（设置 → 隐私和安全性 → 开发者选项），否则创建符号链接要管理员权限。检查是否已启用：\n\n```bash\npowershell -NoProfile -Command '(Get-ItemProperty \"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock\").AllowDevelopmentWithoutDevLicense'\n# 返回 1 = 已启用\n```\n\n## 不需要包装的工具\n\n以下工具本身输出 UTF-8，可直接使用：\n- `git`、`node`、`npm`、`pnpm`、`bun`、`cargo`、`go`\n- bash 内置：`echo`、`cat`、`ls`、`grep` 等\n- `python`：加 `-X utf8` 后可直接使用（见规则 4）\n\n> **编码没问题 ≠ 完全没坑**：这些工具的**输出编码**是干净的，但只要给它们传以 `/` 开头的参数，\n> 仍会被 MSYS2 改写（见规则 6）；`pnpm` 的 workspace 还依赖真符号链接（见规则 7）。\n> 两件事互相独立，别因为「这个工具在白名单里」就放松警惕。\n\nFile v5.1.0:references/shell-routing.md\n\n# Shell 选型（Git Bash / PowerShell / WSL）\n\n主文件给了速查表。需要判断依据、完整决策表、或想知道为什么默认 Git Bash 时读本文。\n\n## 为什么默认 Git Bash\n\n四个独立 agent 在同一台 Windows 10 机器上做同一份任务（zod + TypeScript + vitest，pydantic + pytest，共 9 步），每个只准用一种 shell。实测结果：\n\n| 执行方式 | 输出 token | 轮次 | 失败 | 重试 | 三道闸门 |\n|------|------|------|------|------|------|\n| **Git Bash** | **8,114（基准）** | **34** | **0** | **0** | 全过 |\n| WSL → `/mnt/d` | 11,543（1.42x） | 34 | 0 | 1（静默） | 全过 |\n| WSL → ext4 | 15,159（1.87x） | 49 | 1 | 2 | 全过 |\n| pwsh 7 | 18,808（**2.32x**） | 46 | 0 | 0 | 全过 |\n\n另一组 12 个典型场景的合成基准独立复现了同一系数：PowerShell 5.1 的输出体积是 POSIX 的 **2.22 倍**（同一个「文件不存在」错误，POSIX 是 50 字节一行，PS 5.1 是 370 字节七行）。\n\n命令启动开销（中位数，发 100 条命令的累计代价）：\n\n| Git Bash | `wsl.exe` | PowerShell 5.1 | pwsh 7 |\n|------|------|------|------|\n| 0.064s（6.4s） | 0.130s（13.0s） | 0.189s（18.9s） | 0.216s（21.6s） |\n\n三条结论：\n\n- **Git Bash 是唯一零失败零重试的一臂**，且 token 最省。\n- **PowerShell 不是「更容易出错」，而是「更啰嗦」**——它同样零失败，但写同样的东西用了 80 条语句（Git Bash 38 条），错误对象带调用栈、字符位置、CategoryInfo、FullyQualifiedErrorId 一起打印。\n- **token 消耗与文件系统快慢无关，只与踩坑次数有关**：跑在最快的 ext4 上那一臂，因为踩了两个 `wsl.exe` 的坑、多花 15 轮，反而 token 最高。\n\n## 决策表\n\n| 你要做的事 | 用哪个 | 理由 |\n|------|------|------|\n| npm / pnpm / node / npx / tsc / vitest / jest | **Git Bash** | 直通，零摩擦 |\n| python / pip / venv / pytest | **Git Bash** | 直通（venv 见下方坑 3） |\n| git 全套 | **Git Bash** | 原生，且 worktree 在 WSL 里根本用不了 |\n| **native 模块编译**（node-gyp + MSVC） | **Git Bash** | 与 pwsh **完全等价**：产物字节数相同，都经 vswhere 找到同一套 VS 工具链 |\n| ssh / scp / git over ssh | **Git Bash** | 与 Windows 共用 `~/.ssh`，密钥无需 chmod（见坑 5） |\n| curl / grep / sed / awk / find / jq* | **Git Bash** | POSIX 工具链（`jq` 需另装，见坑 4） |\n| Windows 服务、注册表、事件日志、计划任务、证书 | **PowerShell** | Git Bash 没有对应能力 |\n| 需要 .NET 类型 / COM 对象 / 对象管道 | **PowerShell** | 硬边界，无替代 |\n| 需要管理员权限 | **交给人做** | UAC 弹窗 agent 点不了，命令会挂死 |\n| 跑 Makefile / 需要 gcc、rsync | **WSL** | Git Bash 的 MSYS2 工具集撑不住 |\n| 重 I/O 的构建（大型 monorepo 反复编译） | **WSL + 项目放 ext4** | 见下方「什么时候才值得上 WSL」 |\n\n## 必须切 PowerShell 的四类\n\n这四类没有 Git Bash 替代品，别硬试：\n\n1. **Windows 系统层面** —— `Get-Service` / `Get-ScheduledTask` / `Get-WinEvent` / `Get-NetTCPConnection` / 证书存储 / 注册表写入。\n2. **.NET 与 COM** —— `[System.Guid]::NewGuid()`、`New-Object -ComObject`、任何 `[类型]::方法()` 调用。\n3. **对象管道** —— 需要 `Select-Object Id,WS` 这种结构化字段筛选，而不是文本切割时。\n4. **提权操作** —— 但注意：**这类应该交给人执行**。Git Bash 没有 `sudo`，唯一提权路径是 `Start-Process -Verb RunAs`，它会弹 UAC，agent 无法点击，命令就一直挂着。需要管理员权限的步骤，写进说明让人来做，不要让 agent 去试。\n\n切过去的正确写法是**单条命令**，不是切换会话：\n\n```bash\n# 在 Git Bash 里调一条 PowerShell，用完即回\npowershell -NoProfile -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; (Get-Service wuauserv).Status'\n```\n\n外层务必单引号（防 bash 展开 `$_`、`$null`），UTF-8 前缀对 PS 5.1 必需——细节见 `windows-shell` skill 规则 1。\n\n## 反模式\n\n| 别这样 | 该这样 |\n|------|------|\n| 因为「Windows 就该用 PowerShell」而默认 PowerShell | 默认 Git Bash，只在四类边界处单条切过去 |\n| 为了性能把 Windows 盘上的项目改用 WSL 操作 | 要么整个搬进 ext4，要么留在 Git Bash。别跨 `/mnt/*` |\n| 用小 demo 验证「WSL 访问 `/mnt` 快不快」 | 惩罚随规模放大，小项目试不出来 |\n| 让 agent 尝试提权 | UAC 弹窗会挂死，写进说明让人做 |\n| 遇到报错先怀疑编码 | 先分清：乱码 → 编码问题；语法错/找不到文件 → 参数被改写 |\n| 整个会话切到 PowerShell 或 WSL | 单条命令切换，主线留在 Git Bash |\n\n## 一句话总结\n\n**Git Bash 做主力，PowerShell 管 Windows 系统层面，WSL 只在项目能整个住进 ext4 时才值得。** 三者是分工，不是替代——而分工的默认值应该是 Git Bash。\n\nFile v5.1.0:references/wsl.md\n\n# WSL：值不值得上，以及必知陷阱\n\n考虑把项目搬进 WSL、或已在 WSL 中遇到问题时读本文。\n\n## 什么时候才值得上 WSL\n\nWSL 的优势只有一个来源：**ext4 原生文件系统**。而它成立的前提是**项目文件真的放在 ext4 里**。\n\n| 操作 | ext4（WSL 原生） | NTFS（Windows 原生） | `/mnt/*`（WSL 访问 Windows 盘） |\n|------|------|------|------|\n| tsc 类型检查 | 1.00x | 1.52x | **4.93x** |\n| vitest | 1.00x | 2.36x | **9.69x** |\n| 3000 个小文件增删查 | 1.00x | 8.96x | **54.2x** |\n\n**判定规则：**\n\n- 项目在 `C:\\` / `D:\\` 上 → **不要用 WSL 操作它**。`/mnt/*` 走 9p 协议逐文件跨界，比纯 Windows 还慢 4–6 倍，而且惩罚随项目规模线性放大（文件数 ×3.5，惩罚 ×2）。小 demo 上试不出来，真项目上卡死。\n- 项目能整个搬进 WSL 的 `~/` 且构建密集 → 值得，编译测试全项最快。\n- 只是想跑 `make`、`gcc`、`rsync` → 值得，但记得项目也要在 ext4。\n- 其它情况 → 留在 Git Bash。\n\n**用 WSL 时必须知道的两件事：**\n\n```bash\n# 1) 不要用 wsl.exe -- bash -c '<脚本>' 传复杂脚本\n#    wsl.exe 会用 WSL 登录环境预展开变量，脚本内定义的变量被吞成空，且退出码仍为 0\nwsl.exe -d Ubuntu -- bash -c 'i=3; echo \"$((i+1))\"'   # → 1（错误数字，无报错）\n\n# 正确：走 stdin\nwsl.exe -d Ubuntu -- bash -s <<'EOF'\ni=3; echo \"$((i+1))\"                                   # → 4\nEOF\n\n# 2) 命令先落盘再取退出码，别指望行内 echo\n#    进度条的回车符经 wsl.exe 回传时会互相覆盖，echo $? 整行可能消失\nwsl.exe -d Ubuntu -- bash -s <<'EOF'\nnpx vitest run > /tmp/t.log 2>&1; echo \"EXIT=$?\"; tail -6 /tmp/t.log\nEOF\n```\n\n另外：**git worktree 在 WSL 里完全不可用**——`.git` 文件里存的是 `D:/...` 盘符路径，Linux 的 git 解析不了，直接 fatal。\n\nFile v5.1.0:CHANGELOG.md\n\n# windows-shell 更新日志\n\n版本号与 `SKILL.md` frontmatter 的 `version` 严格一致，由测试看守；\n发布脚本按版本号从本文件提取对应段落作为 changelog。\n\n## 5.1.0\n\n新增一条静默失败陷阱，来自一次「能不能砍得更狠」的对照实验。\n\n**PS 5.1 读无 BOM 的 UTF-8 文件，不显式写 `-Encoding UTF8` 会静默算错行数。**\n实测：一个 3 行的 UTF-8 文件，某行末尾字节为 `a1 8c 0a`，PS 按 GBK 把 `8c` 当作\n双字节前导、吞掉紧随的换行，`Get-Content` 返回 **2 行**，而 `$?` 仍是 `True`。\n这不是「可能乱码」那种显眼的错，是结果错但不报错——性质与规则 1 的参数改写完全相同。\n\n原表格里虽有「UTF-8 → `-Encoding UTF8`」一行，但那是当作普通对照写的，读者会以为\n不加只是可能乱码。现升格为显式警告，并在开头的判别表中增设**「静默失败」**一类：\n没报错但结果就是不对（参数变了值、行数少一行）→ 必须交叉验证。\n\n发现过程：为回答「规范还能不能更省」，做了一版 1.9KB 的极简规范（只保留实测中模型\n真正做错的两条）做对照。结果是**砍过头会反弹**：\n\n| 规范 | 命令数 | 总 token（vs 无规范） |\n|------|------|------|\n| 无 | 19.2 | 1.00x |\n| 18 KB 全量 | 15.8 | 1.43x |\n| **6.4 KB 按需（本版基线）** | **11.2** | **0.87x** |\n| 1.9 KB 极简 | 17.5 | 1.01x |\n\n砍掉 4.5KB 省下的阅读量，被多出来的 6.3 条试错命令吃光还倒亏。四个 agent 共列出\n23 条「规范没写、只能靠自有知识补」的缺口——编码判定方法、venv/pytest 具体命令、\nPython 转码写法各被点名 3–4 次。模型确实「会」，但每次现推都要花命令。\n\n结论：**6.4KB 附近就是这套规范的成本最优点**，再砍会反弹。而极简版意外撞出的这条\n静默失败，恰恰证明了「模型自己会」的那些条目不能省——g4 就是栽在被我砍掉的那一行上。\n\n## 5.0.0\n\n结构性变更：改为**按需展开**，并把 `windows-shell-routing` 合并进来。\n\n起因是一组 A/B 实测。四臂各跑 4 次同一个 Windows 任务（16 次运行），结论有两条：\n\n- **skill 的作用是精确的，不是普遍的。** 16 次里唯一 100% 分离的指标是「参数被静默改写」\n  这一步——无 skill 组 0/4 一次通过，读了规范的三组 12/12 全部一次通过。其余步骤靠常识\n  也能过，测不出差别。\n- **篇幅不等于价值。** 只读 10KB routing 的一组，总 token 是无 skill 组的 1.09 倍；\n  只读 18KB windows-shell 的一组是 1.43 倍、耗时 1.31 倍——而两组在那个关键步骤上\n  效果完全相同。多出来的 8KB 没有兑现任何行为差异。\n\n所以把一次性全量加载改成按需加载：\n\n- `SKILL.md` 缩到 138 行 / 5.8KB，只保留实测中真正拉开差距的内容：两类问题的判别、\n  shell 选型速查、五条高频规则、一次性环境配置，以及一张「遇到什么读哪个」的索引表。\n- 细节移入 `references/`（25KB，5 个文件）：`encoding.md`、`msys2.md`、\n  `shell-routing.md`、`gitbash-pitfalls.md`、`wsl.md`。规则原文一字未改，只是换了位置。\n- **默认加载量降到原来的 20%**（28.3KB → 5.8KB），完整信息量不减。\n\n合并 `windows-shell-routing`：该技能的全部内容进入 `references/shell-routing.md`、\n`wsl.md`、`gitbash-pitfalls.md`，选型速查表上浮到主文件第二节。之所以能合并，正是因为\n有了按需加载——此前拒绝合并的理由是「两者相加 527 行太长」，那个理由现在不成立了。\n原 slug 走 ClawHub 重定向。\n\n测试相应增加渐进式披露的守卫：主文件体积上限、references 链接必须可解析、不得有孤儿\n文件、以及七个「逃生开关」必须存在于 bundle 中的某处（它们是实测中真正改变了 agent\n行为的部分）。\n\n**发布前做了效果验证，并据此回填了两条。** 首版拆分后重跑同一任务，发现第 1 步\n（GBK 遗留文件转码）的一次通过率从 4/4 掉到 1/4——四个 agent 都正确判出了 GBK，却有\n三个先去试 `iconv`，撞上「Git Bash 没有 iconv」；那条提示被我移进了 references，\n主文件只剩一个指针。同时有三个 agent 点名想查「PS 5.1 怎么写无 BOM 的 UTF-8」，\n主文件只警告了陷阱、没给配方。\n\n于是把这两条回填主文件（新增第 4 条「Git Bash 少几个你以为有的工具」，并在第 3 条\n补上 `WriteAllText` + `UTF8Encoding($false)` 的写法），主文件从 5.8KB 到 6.4KB。\n重跑验证：第 1 步回到 4/4，命令数 11.2（六臂最低），总 token 相对无规范 0.87x\n——**是所有方案里唯一比不用规范还便宜的**。相对拆分前的 18KB 全量版：\ntoken 0.60x、耗时 0.54x、命令 0.71x。\n\n跨模型交叉验证（经腾讯 TokenHub 调 deepseek-v3.2 / v4-flash / v4-pro / kimi-k3 /\nminimax-m3 五个模型，各 6 道知识探针）：回填后「Git Bash 有无 iconv」一题从 1/5\n修正到 5/5。另有一条稳定的发现——`MSYS_NO_PATHCONV` 这个解法，五个模型两轮共 10 次\n裸问**没有一次答对**，而给了规范后 5/5 全对。模型知道参数会被改写，却不知道怎么解决；\n这正是本技能存在的意义所在。\n\n**一个诚实的限制**：两轮共 8 次运行中，agent 读取 references 的次数是 **0**，\n全部自评「主文件够用」。所以当前成立的其实是「主文件压缩到够用 + 附录供人查阅」，\n而不是 agent 会自己按指针去取。今后往 references 放内容需按此前提判断：\n凡是 agent 真正需要的，必须留在主文件里。\n\n## 4.4.0\n\n新增 MSYS2 参数改写规则，并修正三处经复测证伪的旧结论。稳定性结论均为 12 次采样，\n不再是单次观察。\n\n修正：\n\n- **pwsh 7 不再标注「输出可能乱码（实测不稳定）」**。实测 12/12 稳定 UTF-8。\n  UTF-8 前缀只对 PS 5.1 必需；外部程序（node/python）的输出穿过 PowerShell 不会被改，\n  两侧都不受影响。规则 1 改为一张按「中文来源 × 是否加前缀」划分的实测表。\n- **`reg query` 移出编码禁用表**。它的失败是 MSYS2 把注册表路径当 Unix 路径改写\n  （报「无效语法」而非乱码），加 `MSYS_NO_PATHCONV=1` 后原命令即可正常工作，与编码无关。\n  规则 3 因此拆为 A 类（真编码问题：wmic/systeminfo/ipconfig/netstat/tasklist/net user）\n  与 B 类（参数改写：reg query/findstr/schtasks），两类解法完全不同。\n- **规则 4 补上前提**。配好用户级 `PYTHONUTF8` 后裸 `python -c` 已经正常；\n  `-X utf8` 的价值在于不依赖环境（CI、容器、别人的机器），而非「不加必乱码」。\n  附反证：清空该变量后 `getpreferredencoding` 立刻退回 `cp936`。\n\n新增（原规则 6/7/8 顺延为 8/9/10）：\n\n- **规则 6：MSYS2 会改写以 `/` 开头的参数**。`/api/v1/users` 被改写成\n  `D:/Program Files/Git/api/v1/users`，`/S /C` 变成 `S:/ C:/`，Docker 的 `-v` 参数被吃掉。\n  最坏的是它**静默生效**——不报错、退出码正常、参数已经变了。给出\n  `MSYS_NO_PATHCONV` / `MSYS2_ARG_CONV_EXCL` / 双斜杠三种解法，并说明为什么不能全局导出\n  （会让 `/c/Users/...` 这类本该转换的参数也不转）。\n- **规则 7：`ln -s` 默认产出普通文件副本**，影响 pnpm workspace / npm link；\n  `MSYS=winsymlinks:nativestrict` 可修，附开发者模式检查命令。\n\n另新增开头的「两类问题，别混为一谈」判别小节（乱码 → 编码；语法错/找不到文件 → 参数改写），\n并在「不需要包装的工具」白名单下注明：输出编码干净 ≠ 没坑。\n\n## 4.3.0\n\n修正「一键配置」那行：原文写的 `npx win-encoding-fix install --setup-env` 从来没能工作过\n——该包从未发布到 npm，且 npx 解析的是包名而不是 bin 名。改为从仓库执行\n`node bin/cli.js setup-env`。仓库已重构为 skill-factory（Skill 工厂）多技能布局，\n本技能现位于 `skills/windows-shell/`；ClawHub slug、安装目录名与 frontmatter 的 name\n仍然都是 `windows-shell`，未发生变化。bundle 内容现为 SKILL.md + CHANGELOG.md。\n编码规则正文无改动。\n\n## 4.2.0\n\n修复 setup-env 的 Windows 用户级环境变量根本没设成功的 bug（嵌套双引号被 cmd.exe 吞掉）；\nSKILL.md 补充 GBK 遗留文件读取、UTF-8 BOM、Out-File 默认 UTF-16、stdin/InputEncoding、\n原始字节工具等编码陷阱；CLI 支持多盘 OpenClaw、失败时退出非零、参数解析健壮化；\n测试全程隔离 HOME 并大幅提升覆盖。\n\nFile v5.1.0:skill-card.md\n\n## Description:\n\nWindows command-line guidance for choosing Git Bash, PowerShell, or WSL and avoiding encoding, MSYS2 argument rewriting, path, virtual environment, and Git configuration pitfalls on Windows 10/11.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chenmo0414](https://clawhub.ai/user/chenmo0414)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and engineering agents use this skill to run command-line workflows on Windows 10/11 with the right shell and safer handling of encoding, MSYS2 path conversion, WSL boundaries, Python/Node tooling, Git, and virtual environments.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Optional setup snippets can change user-level Python encoding variables, shell profile files, and global Git settings.\n\nMitigation: Review each setup command before applying it and limit changes to user-level configuration unless an operator explicitly approves broader changes.\n\nRisk: The skill includes shell routing guidance for Windows workflows and is not a basis for an agent to perform administrator-only UAC actions.\n\nMitigation: Keep administrator-only actions as human-executed steps and avoid commands that wait on an unattended UAC prompt.\n\n## Reference(s):\n\n- [Skill release page](https://clawhub.ai/chenmo0414/skills/windows-shell)\n- [Project homepage](https://github.com/Chenmo0414/win-encoding-fix)\n- [Encoding details](references/encoding.md)\n- [MSYS2 argument rewriting and symlinks](references/msys2.md)\n- [Shell routing](references/shell-routing.md)\n- [Git Bash pitfalls](references/gitbash-pitfalls.md)\n- [WSL guidance](references/wsl.md)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Shell commands, Configuration instructions]\n\n**Output Format:** [Markdown guidance with inline shell and PowerShell command examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Outputs are advisory and should be reviewed before applying user-level environment variable, shell profile, or global Git configuration changes.]\n\n## Skill Version(s):\n\n5.1.0 (source: server release metadata and SKILL.md frontmatter)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v5.0.0: 9 files, 23440 bytes\n\nFiles: CHANGELOG.md (7010b), references/encoding.md (12160b), references/gitbash-pitfalls.md (2525b), references/msys2.md (3455b), references/shell-routing.md (5061b), references/wsl.md (1929b), skill-card.md (2349b), SKILL.md (6413b), _meta.json (132b)\n\nFile v5.0.0:SKILL.md\n\n---\nname: windows-shell\nversion: 5.0.0\ndescription: \"Windows 命令行工作规范：先选对 shell（默认 Git Bash），再避开编码与 MSYS2 参数改写两类陷阱。覆盖 GBK/UTF-8、BOM、MSYS2 路径转换、PowerShell/pwsh、WSL 判定、Python/Node.js、Git 配置与代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。细节按需读 references/。\"\nlicense: MIT\nmetadata:\n  openclaw:\n    emoji: \"🪟\"\n    os: [windows]\n    homepage: \"https://github.com/Chenmo0414/win-encoding-fix\"\n---\n\n# Windows 命令行工作规范\n\n用户系统：Windows 10/11（代码页 GBK/936），终端：MSYS2/Git Bash。\n\n**本文件是速查与路由表。** 每条规则下面标了「细读」，只在真正遇到那类问题时再去读对应的\n`references/` 文件——不要一次性全部读完。\n\n## 一、先分清是哪一类问题\n\n在 Git Bash 里执行命令出问题，绝大多数是这两类之一。**先判类，再套解法**，两类的解法完全不通用：\n\n| 症状 | 类别 | 第一反应 |\n|------|------|------|\n| 输出乱码（`涓枃`、`M-DM-c`、方块字） | **编码** | 让源头输出 UTF-8 |\n| 报「无效语法 / invalid / 找不到文件」，或参数悄悄变了值 | **MSYS2 参数改写** | `MSYS_NO_PATHCONV=1` |\n\n拿编码的解法去治参数改写，怎么加前缀都不好使——这是最常见的误诊。\n\n## 二、选对 shell（默认 Git Bash）\n\n| 你要做的事 | 用哪个 |\n|------|------|\n| npm / node / npx / tsc / vitest / python / pip / pytest / git / ssh | **Git Bash** |\n| Windows 服务、注册表、事件日志、计划任务、证书、.NET/COM、对象管道 | **PowerShell**（单条命令切过去，主线不搬家） |\n| 跑 Makefile、需要 gcc/rsync，或重 I/O 构建且项目能整个搬进 ext4 | **WSL** |\n| 需要管理员权限 | **交给人做**——UAC 弹窗 agent 点不了，命令会一直挂着 |\n\n项目文件在 `C:\\`/`D:\\` 上时，**不要用 WSL 去操作它**：跨 `/mnt/*` 比纯 Windows 还慢 4–6 倍，\n且惩罚随项目规模线性放大。\n\n> 细读：判断依据与完整决策表 → [shell-routing.md](references/shell-routing.md)；\n> WSL 值不值得上 → [wsl.md](references/wsl.md)\n\n## 三、必须知道的六条\n\n下面六条是实测中真正拉开差距的。其余规则都在 `references/`。\n\n### 1. 以 `/` 开头的参数会被静默改写\n\nGit Bash 把它当 Unix 路径转成 Windows 路径再传给原生程序。**不报错、退出码 0、参数已经变了**：\n\n```bash\nnode app.js /api/v1/users          # 程序实收 D:/Program Files/Git/api/v1/users\ndocker run -v /app:/app ...        # -v 后面被吃掉\nreg query \"HKCU\\Environment\"       # 错误: 无效语法。\n```\n\n```bash\nMSYS_NO_PATHCONV=1 node app.js /api/v1/users    # 单条前置，不要全局导出\n```\n\n全局导出会让 `/c/Users/...` 这类本该转换的参数也不转。\n\n> 细读：另两种绕法、符号链接退化 → [msys2.md](references/msys2.md)\n\n### 2. PowerShell 5.1 输出中文必须加前缀\n\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; 你的命令'\n```\n\n外层用**单引号**（防 bash 展开 `$_`、`$null`）。pwsh 7 不需要这个前缀，加了也无害。\n外部程序（node/python）自己写的 UTF-8 穿过 PowerShell 不会被改。\n\n### 3. 读遗留文件前先验编码，别硬套 UTF-8\n\n对一个真正的 GBK/936 文件强加 `-Encoding UTF8` 会读出乱码。先看字节再决定：\n\n```bash\nod -c legacy.txt | head -2        # 或 xxd；Git Bash 没有 hexdump\n```\n\n| 文件真实编码 | PS 5.1 | pwsh 7 |\n|------|------|------|\n| UTF-8 | `-Encoding UTF8` | 默认即可 |\n| GBK/936 | `-Encoding Default` | `[System.Text.Encoding]::GetEncoding(936)` |\n\n**写出去也有坑**：PS 5.1 的 `-Encoding UTF8` 会带 BOM，`>` 重定向默认写 UTF-16。要无 BOM 的 UTF-8：\n\n```powershell\n[System.IO.File]::WriteAllText(\"out.txt\", $s, (New-Object System.Text.UTF8Encoding($false)))\n```\n\n> 细读：更多 BOM/重定向陷阱、`$OutputEncoding`、传统 CMD 工具替代表\n> → [encoding.md](references/encoding.md)\n\n### 4. Git Bash 少几个你以为有的工具\n\n`iconv`、`jq`、`make`、`gcc`、`rsync`、`hexdump` **都没有**。转码不要指望 `iconv`，\n验字节用 `od -c`，其余场景改用 Python 或 Node 顶上；真需要完整 GNU 工具链就上 WSL。\n\n```bash\npython -c \"import io;io.open('out.txt','w',encoding='utf-8').write(io.open('in.txt',encoding='gbk').read())\"\n```\n\n### 5. 生成代码时显式写编码，不依赖环境\n\n```python\nopen('data.txt', encoding='utf-8')          # 裸 open() 在 Windows 上默认 cp936\n```\n\n```bash\npython -X utf8 -c \"...\"                      # 单行命令，不假设 PYTHONUTF8 已生效\n```\n\n环境变量会失效，代码里的显式声明不会。\n\n### 6. venv 直接调解释器，绕开 activate\n\n```bash\n./.venv/Scripts/python.exe -m pytest         # source activate 会拼出正反斜杠混拼的畸形路径\n```\n\n同理，管道会吞掉上游退出码，要用 `set -o pipefail` 或 `${PIPESTATUS[0]}`。\n\n> 细读：venv、工具集不全、SSH 密钥、符号链接 → [gitbash-pitfalls.md](references/gitbash-pitfalls.md)\n\n## 四、一次性环境配置\n\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8;\n  [Environment]::SetEnvironmentVariable(\"PYTHONUTF8\", \"1\", \"User\");\n  [Environment]::SetEnvironmentVariable(\"PYTHONIOENCODING\", \"utf-8\", \"User\")'\ngit config --global core.quotepath false\ngit config --global core.autocrlf input\n```\n\n写进 `~/.bash_profile` 的变量**非登录 shell 不会加载**（agent 正是这种 shell），\n所以要设成 Windows 用户级环境变量。\n\n> 细读：完整配置与每条的理由 → [encoding.md](references/encoding.md) 的「环境前置条件」\n\n## 五、按需索引\n\n| 遇到什么 | 读哪个 |\n|------|------|\n| 乱码、BOM、UTF-16、GBK 遗留文件、CMD 工具替代 | [encoding.md](references/encoding.md) |\n| 参数被改写、符号链接变成副本 | [msys2.md](references/msys2.md) |\n| 不确定该用哪个 shell、想看实测依据 | [shell-routing.md](references/shell-routing.md) |\n| venv、工具缺失、SSH 密钥、管道退出码 | [gitbash-pitfalls.md](references/gitbash-pitfalls.md) |\n| 要不要上 WSL、`wsl.exe` 变量吞噬 | [wsl.md](references/wsl.md) |\n\nFile v5.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn78ryxatfm99gvwnvgexh8hkx847bk7\",\n  \"slug\": \"windows-shell\",\n  \"version\": \"5.0.0\",\n  \"publishedAt\": 1787152806349\n}\n\nFile v5.0.0:references/encoding.md\n\n# 编码细节（GBK / UTF-8 / BOM）\n\n主文件 `SKILL.md` 只放了最常用的两条。遇到下列任一情况时读本文：\n读写文件出现乱码、需要处理 GBK 遗留文件、需要写无 BOM 的 UTF-8、\nPowerShell 重定向编码不对、管道方向的编码问题、传统 CMD 工具输出乱码。\n\n## 环境自检（开工前可选执行）\n\n判断当前 shell 的编码是否已正确配置：\n\n```bash\npython -c \"import sys; print('utf8_mode=', sys.flags.utf8_mode)\"   # 期望 1；为 0 说明 Python 默认 GBK\necho \"PYTHONUTF8=$PYTHONUTF8\"                                       # 期望 1；为空说明环境变量未加载\n```\n\n**关键认知**：`PYTHONUTF8` 等变量若只写在 `~/.bash_profile`，**非登录 / 非交互 shell 不会加载它**（AI 助手与脚本通常正是这种 shell）。因此：\n\n- 持久生效请配置 **Windows 用户级环境变量**（被所有进程继承，重启终端后生效）；\n- 当前会话内最可靠的做法是**每条命令显式带编码参数**（见下方各规则）。\n\n## 环境前置条件（持久配置，建议一次性执行）\n\n```bash\n# 1) Windows 用户级环境变量 —— 最可靠，所有进程继承（重启终端后生效）\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8;\n  [Environment]::SetEnvironmentVariable(\"PYTHONUTF8\", \"1\", \"User\");\n  [Environment]::SetEnvironmentVariable(\"PYTHONIOENCODING\", \"utf-8\", \"User\")'\n\n# 2) bash 显示相关变量（登录 shell 用），并让 .bashrc 也加载，覆盖非登录交互 shell\ncat >> ~/.bash_profile <<'EOF'\nexport PYTHONUTF8=1\nexport PYTHONIOENCODING=utf-8\nexport LANG=en_US.UTF-8\nexport LESSCHARSET=utf-8\nEOF\ngrep -q 'bash_profile' ~/.bashrc 2>/dev/null || echo '[ -f ~/.bash_profile ] && . ~/.bash_profile' >> ~/.bashrc\n\n# 3) Git 全局配置\ngit config --global core.quotepath false        # 中文文件名正常显示\ngit config --global core.autocrlf input         # 提交 LF，检出保持原样\ngit config --global i18n.commitEncoding utf-8    # commit 消息 UTF-8\ngit config --global i18n.logOutputEncoding utf-8\ngit config --global core.pager \"less -R\"\n```\n\n> 一键配置：在 [skill-factory](https://github.com/Chenmo0414/win-encoding-fix) 仓库里执行 `node bin/cli.js setup-env`\n\n### 规则 1：PowerShell 命令必须加 UTF-8 前缀 + 外层单引号\n\n```bash\n# 标准模板（外层单引号 + UTF-8 前缀）\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; 你的命令'\n```\n\n**两个要点必须同时满足：**\n- `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8` — 不加则中文输出乱码\n- 外层**单引号** — 防止 bash 把 `$_`、`$null` 当作 bash 变量展开\n\n仅当命令中不含 `$` 变量时才可用外层双引号。\n\n**前缀到底什么时候必需**（v4.3.0 实测，各采样 12 次，结果完全稳定）：\n\n| 中文的来源 | PS 5.1 无前缀 | PS 5.1 加前缀 | pwsh 7 无前缀 |\n|------|------|------|------|\n| PowerShell 自己产出（`Write-Output`、cmdlet 结果） | **GBK ×12 → 乱码** | UTF-8 ×12 ✅ | **UTF-8 ×12 ✅** |\n| 外部程序产出（`node -e`、`python` 等） | UTF-8 ×12 ✅ | UTF-8 ×12 ✅ | UTF-8 ×12 ✅ |\n\n- **PS 5.1 必须加前缀**：只要中文由 PowerShell 自己产出，不加就是稳定乱码，没有侥幸。\n- **pwsh 7 不需要前缀**：实测 12/12 稳定 UTF-8。加了无害，脚本要兼容 5.1 时统一加是合理的，但不必因为「怕 pwsh 不稳」而加。\n- **外部程序的输出不受影响**：`node`/`git`/`python` 自己写 UTF-8 到 stdout，穿过 PowerShell 不会被改。所以「PS 包装」只对遵守控制台代码页的 Windows 原生工具才有意义（见规则 3）。\n\n### 规则 2：PowerShell 读写文件 —— `-Encoding` 必须匹配文件真实编码\n\n**读 UTF-8 文件**：PowerShell 5.1 不加 `-Encoding UTF8` 会用 GBK 读取，实测 `中文` → `涓枃`。\n\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Content \"path\\file.txt\" -Encoding UTF8'\n```\n\n**⚠️ 读 GBK 遗留文件（本机最常见）**：反过来，对一个真正的 GBK/936 文件强加 `-Encoding UTF8` 会**读出乱码**。`-Encoding` 的值必须等于文件的真实编码：\n\n| 文件真实编码 | PS 5.1 读法 | pwsh 7 读法 |\n|------|------|------|\n| UTF-8 | `-Encoding UTF8` | 默认即可（或 `-Encoding utf8`） |\n| GBK/936（遗留） | `-Encoding Default` 或不加 | `-Encoding oem` 或 `[System.Text.Encoding]::GetEncoding(936)` |\n\npwsh 7 默认按 UTF-8 读，遇到 GBK 文件反而会 mojibake，此时**必须显式指定 936**。\n\n**写文件的 BOM 陷阱**：PS 5.1 的 `Set-Content -Encoding UTF8` / `Out-File -Encoding UTF8` 会写入 **UTF-8 BOM**（`EF BB BF`），很多工具（旧编译器、某些 JSON 解析器、shell 脚本）会因此报错。要写**无 BOM** UTF-8：\n\n```powershell\n# PS 5.1 无 BOM 写法\n[System.IO.File]::WriteAllText(\"out.txt\", $content, (New-Object System.Text.UTF8Encoding($false)))\n# pwsh 7\nSet-Content out.txt -Value $content -Encoding utf8NoBOM\n```\n\n**输出重定向的编码**：PS 5.1 的 `>` 和 `Out-File` **默认写 UTF-16 LE**，不是 UTF-8。若要把命令输出存成 UTF-8 文件给后续读取，务必显式 `... | Out-File -Encoding utf8 out.txt`（注意上面的 BOM 说明），或捕获字符串后用 .NET 写。\n\n**stdin / 管道方向**：`[Console]::OutputEncoding` 只管 PowerShell **输出**。若要把 UTF-8 内容通过管道**喂进** PowerShell（`echo ... | powershell ...`），还需 `[Console]::InputEncoding = [System.Text.Encoding]::UTF8`；而 PowerShell **管道给下游原生命令**（如 `... | findstr`）用的是 `$OutputEncoding` 变量（默认 ASCII，会丢中文）。能用内联 `-Command` 参数就别走 stdin 管道。\n\n### 规则 3：禁止直接使用传统 CMD 工具和 cmd /c\n\n传统 CMD 工具多数输出 GBK 或 UTF-16，在 UTF-8 终端中乱码。`cmd /c` 同样不可用——`chcp 65001` 无法修复子进程编码（实测 `cmd /c \"chcp 65001 & echo 你好\"` 仍乱码）。\n\n但**并非全都是编码问题**。实测把它们分成了两类，解法完全不同：\n\n**A 类 —— 真·编码问题**（实测输出 GBK 字节，PS 包装可解决）：\n\n| 禁止 | 替代 |\n|------|------|\n| `wmic` | `Get-CimInstance` |\n| `systeminfo` | `Get-ComputerInfo` 或 PS 包装 `systeminfo` |\n| `ipconfig` | `Get-NetIPAddress` / `Get-NetIPConfiguration` |\n| `netstat` | `Get-NetTCPConnection` |\n| `tasklist` | `Get-Process` |\n| `net user` | `Get-LocalUser` |\n| `sc query` | `Get-Service`（英文输出时不乱码，但中文服务名会） |\n| `cmd /c` | **永远不用** |\n\n**B 类 —— 其实是 MSYS2 参数改写，不是编码问题**（实测：加 `MSYS_NO_PATHCONV=1` 后原命令即可正常工作）：\n\n| 命令 | 默认失败表现 | 真实原因 |\n|------|------|------|\n| `reg query \"HKCU\\Environment\"` | `错误: 无效语法。` | 注册表路径被当成 Unix 路径改写 |\n| `findstr 中文 /tmp/x.txt` | `FINDSTR: 无法打开 C:x.txt` | `/tmp/x.txt` 被改写成 `C:x.txt` |\n| `schtasks /query /tn \"\\...\"` | 参数错误 | 同上 |\n\nB 类仍然**建议**换成 `Get-ItemProperty` / `Select-String` / `Get-ScheduledTask`——PowerShell 版本输出更结构化、也不受 MSYS2 影响。但要知道：**它们不是「因为乱码」才被禁的**，误诊会让你在别处用错解法（比如给一个路径被改写的命令拼命加编码前缀，怎么加都不好使）。\n\n在 PowerShell 中包装传统命令**通常**可正确转码：\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; systeminfo | Select-Object -First 5'\n```\n\n> **注意，包装不是万能的**：`[Console]::OutputEncoding` 只对**遵守控制台输出代码页**的工具有效（`systeminfo`、`ipconfig` 等）。对于**输出固定 GBK 字节或原始字节**的工具（部分第三方 CLI、某些日志），包装后仍是乱码——这类需要「先按 936 解码、再转 UTF-8」：`powershell -Command '$s = (& some.exe) ; [Console]::OutputEncoding = [System.Text.Encoding]::UTF8; [System.Text.Encoding]::GetEncoding(936).GetString(...)'`，或在 Node/Python 侧以**字节**捕获再按真实编码解码（见规则 5、规则 9）。\n\n### 规则 4：Python 命令行执行 —— 优先 `-X utf8`，不要假设环境\n\n实测：AI 助手与脚本运行在**非交互 shell**，若 `PYTHONUTF8` 只写在 `~/.bash_profile`，它不会被加载，`sys.flags.utf8_mode` 为 0，`python -c \"print('你好')\"` 直接乱码。\n\n**注意前提**：一旦按上文「环境前置条件」把 `PYTHONUTF8` 配成了 **Windows 用户级环境变量**，裸 `python -c \"print('你好')\"` 就已经正常了（实测 `utf8_mode=1`、`getpreferredencoding=utf-8`）。所以 `-X utf8` 的价值不是「不加就一定乱码」，而是**不依赖环境是否配好**——在别人的机器、CI、容器里同样成立。这也正是它值得默认带上的理由。\n\n反证：把 `PYTHONUTF8` 清空后再测，`getpreferredencoding` 立刻退回 `cp936`。环境配置是会失效的，代码里的显式声明不会。\n\n**最可靠做法 —— 单行命令显式带 `-X utf8`：**\n```bash\npython -X utf8 -c \"print('你好世界')\"\n# 或临时设环境变量\nPYTHONUTF8=1 python script.py\n```\n\n`-X utf8` 同时让 `print()` 输出与 `open()` 默认读写都走 UTF-8，幂等无副作用，已是 UTF-8 环境时加它也不会出错。**生成代码时**仍应显式写 `encoding='utf-8'`（见规则 8），不依赖运行时标志。\n\n### 规则 5：Node.js 子进程调用系统命令\n\nNode.js 自身输出 UTF-8 没问题，但 `execSync`/`exec`/`spawn` 调用传统 CMD 工具时，输出是 GBK，`toString('utf-8')` 会乱码。\n\n**修复**：让子进程通过 PowerShell 输出 UTF-8：\n```javascript\nexecSync('powershell -Command \"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; systeminfo\"').toString('utf-8')\n```\n\n对于**输出原始 GBK 字节、不认控制台代码页**的工具，PowerShell 包装无效，应以字节捕获再手动解码：\n```javascript\nconst { execSync } = require('child_process')\nconst buf = execSync('some-gbk-tool.exe')       // 拿 Buffer，不要直接 toString\nconst text = new TextDecoder('gbk').decode(buf)  // 按真实编码解码\n```\n\n### 规则 8：Python 文件 I/O 必须指定编码\n\n```python\n# 正确 — 显式指定 encoding\nwith open('data.txt', 'r', encoding='utf-8') as f:\n    content = f.read()\n\nwith open('output.txt', 'w', encoding='utf-8') as f:\n    f.write(content)\n\n# 错误 — 裸 open() 在 Windows 上默认 GBK（实测 locale.getpreferredencoding() = cp936）\nwith open('data.txt', 'r') as f:  # 不要这样写\n    content = f.read()\n```\n\n同样适用于 `json.load`/`json.dump`、`csv.reader`、`pathlib.Path.read_text()` 等需要文件对象的场景。\n\nPython subprocess 调用系统命令时也需注意编码：\n```python\nimport subprocess\nresult = subprocess.run(\n    ['powershell', '-Command', '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Process'],\n    capture_output=True, text=True, encoding='utf-8'\n)\n```\n\n### 规则 9：Node.js 文件操作和子进程编码\n\n```javascript\n// 文件读写 — 显式指定 utf-8\nfs.readFileSync('data.txt', 'utf-8')\nfs.writeFileSync('output.txt', content, 'utf-8')\n\n// 子进程调用 Windows 原生命令 — 通过 PowerShell 包装\nconst { execSync } = require('child_process')\nconst output = execSync(\n  'powershell -Command \"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Service\"'\n).toString('utf-8')\n```\n\n### 规则 10：Git 中文支持\n\n环境已配置 `core.quotepath=false`，中文文件名在 `git status`/`git diff` 中正常显示。\n\n如果发现中文文件名仍显示为 `\\346\\265\\213\\350\\257\\225` 形式，执行：\n```bash\ngit config --global core.quotepath false\n```\n\n## 格式化技巧\n\n- 宽表格加 `| Out-String -Width 200` 防截断\n- `Format-Table -AutoSize` 自适应列宽\n- `Format-List` 展示详细单条记录\n- `Select-Object` 控制返回字段数量\n\nFile v5.0.0:references/gitbash-pitfalls.md\n\n# Git Bash 的五个坑\n\n在 Git Bash 下遇到非编码类异常时读本文：参数被改写、符号链接失效、\nvenv 激活路径异常、工具缺失、SSH 密钥不通用、管道吞退出码。\n\n## Git Bash 的五个坑\n\n选了 Git Bash，这五个必须知道，否则会以为是代码的问题。\n\n### 坑 1：以 `/` 开头的参数会被改写（静默）\n\nMSYS2 把它们当 Unix 路径转成 Windows 路径再传给程序。**不报错、退出码正常、参数已经变了**：\n\n```bash\nnode app.js /api/v1/users     # 程序收到 D:/Program Files/Git/api/v1/users\nprog /S /C                    # → S:/ C:/\ndocker run -v /app:/app ...   # -v 后面被吃掉\n```\n\n```bash\n# 解法：单条命令前置，别全局导出\nMSYS_NO_PATHCONV=1 node app.js /api/v1/users\n```\n\n全局导出会让 `/c/Users/...` 这类你确实希望被转换的参数也不转了。\n\n### 坑 2：`ln -s` 默认产出的是副本\n\n```bash\nln -s t.txt l.txt && ls -l l.txt      # -rw-r--r--  ← 是副本，不是链接\nexport MSYS=winsymlinks:nativestrict  # 修复后 → lrwxrwxrwx\n```\n\n**pnpm workspace、npm link、monorepo 本地依赖都依赖真符号链接**，退化成副本会表现为「改了源码不生效」。需先启用 Windows 开发者模式。\n\n### 坑 3：venv 的 `activate` 会拼出畸形路径\n\n```bash\nsource .venv/Scripts/activate    # VIRTUAL_ENV 丢盘符，路径变成 /d/proj/\\proj\\.venv/Scripts/python\n```\n\n虽然仍能解析，但不可靠。**直接调解释器，绕开 activate**：\n\n```bash\n./.venv/Scripts/python.exe -m pytest\n./.venv/Scripts/python.exe -m pip install -r requirements.txt\n```\n\n### 坑 4：工具集不全\n\n`jq`、`make`、`gcc`、`rsync` 都**没有**。跑 Makefile 的项目直接卡住——那种情况上 WSL，不要试图在 Git Bash 里凑。\n\n### 坑 5：SSH 密钥位置与 WSL 不通用\n\nGit Bash 与 Windows 共用 `C:\\Users\\你\\.ssh`，**WSL 用的是独立的 `/root/.ssh`**。在 Windows 配好的 SSH，到 WSL 里等于从零开始。\n\n而且 `/mnt/*` 上的文件在 WSL 眼里权限是 `777`，OpenSSH 会判定 `bad permissions` 直接忽略该密钥。要在 WSL 里用 ssh，密钥必须复制到 ext4 并 `chmod 600`。Git Bash 没有这个问题（它走 Windows ACL，不看 POSIX 权限位）。\n\n### 附：管道会吞掉退出码\n\n这不是 Git Bash 特有，但 agent 最容易在这里误判成功：\n\n```bash\nnpm install ... | tail -25      # $? 是 tail 的，不是 npm 的\nset -o pipefail                 # 或用 ${PIPESTATUS[0]}\n```\n\nFile v5.0.0:references/msys2.md\n\n# MSYS2 参数改写与符号链接\n\n主文件已给出 `MSYS_NO_PATHCONV=1` 这一条速查。需要完整解释、\n其它两种绕法、或遇到符号链接/工具缺失问题时读本文。\n\n### 规则 6：MSYS2 会改写以 `/` 开头的参数\n\nGit Bash（MSYS2）在把参数交给 **非 MSYS2 程序**（即所有 Windows 原生 .exe）之前，会把看起来像 Unix 路径的参数自动转换成 Windows 路径。这是 MSYS2 的设计，不是 bug——但它**静默生效**，不报错、退出码正常，参数已经变了。\n\n```bash\nnode app.js /api/v1/users\n# 程序实际收到：D:/Program Files/Git/api/v1/users   ← 前面被拼上了 Git 安装目录\n\nprog /S /C                  # → 变成  S:/ C:/\ndocker run -v /app:/app ... # → -v 后面的参数被破坏\nreg query \"HKCU\\Environment\"   # → 错误: 无效语法。\nfindstr 中文 /tmp/x.txt        # → FINDSTR: 无法打开 C:x.txt\n```\n\n**什么时候会中招**：参数以 `/` 开头，且接收方是 Windows 原生程序。典型场景——REST 路径、Docker 卷映射、Windows 风格开关（`/S` `/C` `/query`）、注册表路径、传给 `.exe` 的 Unix 路径。\n\n**三种解法**（均实测有效）：\n\n```bash\n# A. 单条命令临时关闭（推荐，作用域最小）\nMSYS_NO_PATHCONV=1 reg query \"HKCU\\Environment\" /v PYTHONUTF8\nMSYS_NO_PATHCONV=1 node app.js /api/v1/users\n\n# B. 按参数排除\nMSYS2_ARG_CONV_EXCL='*' node app.js /api/v1/users\n\n# C. 双斜杠转义（只想保护单个参数时）\nnode app.js //api/v1/users\n```\n\n**不要全局导出 `MSYS_NO_PATHCONV=1`**：关掉转换后，`/c/Users/...` 这类你确实希望被转成 `C:\\Users\\...` 的参数也不再转换，会引入另一批问题。按需在单条命令前加。\n\n> 与编码问题的区别：编码问题表现为**乱码**，参数改写表现为**语法错/找不到文件/行为不对但不报错**。诊断时先看报错形态，别拿编码的解法去治路径的病。\n\n### 规则 7：Git Bash 的 `ln -s` 默认产出的是副本\n\n```bash\nln -s t.txt l.txt && ls -l l.txt\n# 默认：  -rw-r--r--  ← 普通文件副本，不是链接\n```\n\n对普通脚本无所谓，但 **pnpm workspace、npm link、monorepo 的本地依赖都依赖真符号链接**，退化成副本会导致改了源码却不生效、或磁盘占用异常。\n\n```bash\n# 修复：产出真正的符号链接（lrwxrwxrwx）\nexport MSYS=winsymlinks:nativestrict\nln -s t.txt l.txt && ls -l l.txt      # → lrwxrwxrwx ... l.txt -> t.txt\n```\n\nWindows 10/11 需先启用**开发者模式**（设置 → 隐私和安全性 → 开发者选项），否则创建符号链接要管理员权限。检查是否已启用：\n\n```bash\npowershell -NoProfile -Command '(Get-ItemProperty \"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock\").AllowDevelopmentWithoutDevLicense'\n# 返回 1 = 已启用\n```\n\n## 不需要包装的工具\n\n以下工具本身输出 UTF-8，可直接使用：\n- `git`、`node`、`npm`、`pnpm`、`bun`、`cargo`、`go`\n- bash 内置：`echo`、`cat`、`ls`、`grep` 等\n- `python`：加 `-X utf8` 后可直接使用（见规则 4）\n\n> **编码没问题 ≠ 完全没坑**：这些工具的**输出编码**是干净的，但只要给它们传以 `/` 开头的参数，\n> 仍会被 MSYS2 改写（见规则 6）；`pnpm` 的 workspace 还依赖真符号链接（见规则 7）。\n> 两件事互相独立，别因为「这个工具在白名单里」就放松警惕。\n\nFile v5.0.0:references/shell-routing.md\n\n# Shell 选型（Git Bash / PowerShell / WSL）\n\n主文件给了速查表。需要判断依据、完整决策表、或想知道为什么默认 Git Bash 时读本文。\n\n## 为什么默认 Git Bash\n\n四个独立 agent 在同一台 Windows 10 机器上做同一份任务（zod + TypeScript + vitest，pydantic + pytest，共 9 步），每个只准用一种 shell。实测结果：\n\n| 执行方式 | 输出 token | 轮次 | 失败 | 重试 | 三道闸门 |\n|------|------|------|------|------|------|\n| **Git Bash** | **8,114（基准）** | **34** | **0** | **0** | 全过 |\n| WSL → `/mnt/d` | 11,543（1.42x） | 34 | 0 | 1（静默） | 全过 |\n| WSL → ext4 | 15,159（1.87x） | 49 | 1 | 2 | 全过 |\n| pwsh 7 | 18,808（**2.32x**） | 46 | 0 | 0 | 全过 |\n\n另一组 12 个典型场景的合成基准独立复现了同一系数：PowerShell 5.1 的输出体积是 POSIX 的 **2.22 倍**（同一个「文件不存在」错误，POSIX 是 50 字节一行，PS 5.1 是 370 字节七行）。\n\n命令启动开销（中位数，发 100 条命令的累计代价）：\n\n| Git Bash | `wsl.exe` | PowerShell 5.1 | pwsh 7 |\n|------|------|------|------|\n| 0.064s（6.4s） | 0.130s（13.0s） | 0.189s（18.9s） | 0.216s（21.6s） |\n\n三条结论：\n\n- **Git Bash 是唯一零失败零重试的一臂**，且 token 最省。\n- **PowerShell 不是「更容易出错」，而是「更啰嗦」**——它同样零失败，但写同样的东西用了 80 条语句（Git Bash 38 条），错误对象带调用栈、字符位置、CategoryInfo、FullyQualifiedErrorId 一起打印。\n- **token 消耗与文件系统快慢无关，只与踩坑次数有关**：跑在最快的 ext4 上那一臂，因为踩了两个 `wsl.exe` 的坑、多花 15 轮，反而 token 最高。\n\n## 决策表\n\n| 你要做的事 | 用哪个 | 理由 |\n|------|------|------|\n| npm / pnpm / node / npx / tsc / vitest / jest | **Git Bash** | 直通，零摩擦 |\n| python / pip / venv / pytest | **Git Bash** | 直通（venv 见下方坑 3） |\n| git 全套 | **Git Bash** | 原生，且 worktree 在 WSL 里根本用不了 |\n| **native 模块编译**（node-gyp + MSVC） | **Git Bash** | 与 pwsh **完全等价**：产物字节数相同，都经 vswhere 找到同一套 VS 工具链 |\n| ssh / scp / git over ssh | **Git Bash** | 与 Windows 共用 `~/.ssh`，密钥无需 chmod（见坑 5） |\n| curl / grep / sed / awk / find / jq* | **Git Bash** | POSIX 工具链（`jq` 需另装，见坑 4） |\n| Windows 服务、注册表、事件日志、计划任务、证书 | **PowerShell** | Git Bash 没有对应能力 |\n| 需要 .NET 类型 / COM 对象 / 对象管道 | **PowerShell** | 硬边界，无替代 |\n| 需要管理员权限 | **交给人做** | UAC 弹窗 agent 点不了，命令会挂死 |\n| 跑 Makefile / 需要 gcc、rsync | **WSL** | Git Bash 的 MSYS2 工具集撑不住 |\n| 重 I/O 的构建（大型 monorepo 反复编译） | **WSL + 项目放 ext4** | 见下方「什么时候才值得上 WSL」 |\n\n## 必须切 PowerShell 的四类\n\n这四类没有 Git Bash 替代品，别硬试：\n\n1. **Windows 系统层面** —— `Get-Service` / `Get-ScheduledTask` / `Get-WinEvent` / `Get-NetTCPConnection` / 证书存储 / 注册表写入。\n2. **.NET 与 COM** —— `[System.Guid]::NewGuid()`、`New-Object -ComObject`、任何 `[类型]::方法()` 调用。\n3. **对象管道** —— 需要 `Select-Object Id,WS` 这种结构化字段筛选，而不是文本切割时。\n4. **提权操作** —— 但注意：**这类应该交给人执行**。Git Bash 没有 `sudo`，唯一提权路径是 `Start-Process -Verb RunAs`，它会弹 UAC，agent 无法点击，命令就一直挂着。需要管理员权限的步骤，写进说明让人来做，不要让 agent 去试。\n\n切过去的正确写法是**单条命令**，不是切换会话：\n\n```bash\n# 在 Git Bash 里调一条 PowerShell，用完即回\npowershell -NoProfile -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; (Get-Service wuauserv).Status'\n```\n\n外层务必单引号（防 bash 展开 `$_`、`$null`），UTF-8 前缀对 PS 5.1 必需——细节见 `windows-shell` skill 规则 1。\n\n## 反模式\n\n| 别这样 | 该这样 |\n|------|------|\n| 因为「Windows 就该用 PowerShell」而默认 PowerShell | 默认 Git Bash，只在四类边界处单条切过去 |\n| 为了性能把 Windows 盘上的项目改用 WSL 操作 | 要么整个搬进 ext4，要么留在 Git Bash。别跨 `/mnt/*` |\n| 用小 demo 验证「WSL 访问 `/mnt` 快不快」 | 惩罚随规模放大，小项目试不出来 |\n| 让 agent 尝试提权 | UAC 弹窗会挂死，写进说明让人做 |\n| 遇到报错先怀疑编码 | 先分清：乱码 → 编码问题；语法错/找不到文件 → 参数被改写 |\n| 整个会话切到 PowerShell 或 WSL | 单条命令切换，主线留在 Git Bash |\n\n## 一句话总结\n\n**Git Bash 做主力，PowerShell 管 Windows 系统层面，WSL 只在项目能整个住进 ext4 时才值得。** 三者是分工，不是替代——而分工的默认值应该是 Git Bash。\n\nFile v5.0.0:references/wsl.md\n\n# WSL：值不值得上，以及必知陷阱\n\n考虑把项目搬进 WSL、或已在 WSL 中遇到问题时读本文。\n\n## 什么时候才值得上 WSL\n\nWSL 的优势只有一个来源：**ext4 原生文件系统**。而它成立的前提是**项目文件真的放在 ext4 里**。\n\n| 操作 | ext4（WSL 原生） | NTFS（Windows 原生） | `/mnt/*`（WSL 访问 Windows 盘） |\n|------|------|------|------|\n| tsc 类型检查 | 1.00x | 1.52x | **4.93x** |\n| vitest | 1.00x | 2.36x | **9.69x** |\n| 3000 个小文件增删查 | 1.00x | 8.96x | **54.2x** |\n\n**判定规则：**\n\n- 项目在 `C:\\` / `D:\\` 上 → **不要用 WSL 操作它**。`/mnt/*` 走 9p 协议逐文件跨界，比纯 Windows 还慢 4–6 倍，而且惩罚随项目规模线性放大（文件数 ×3.5，惩罚 ×2）。小 demo 上试不出来，真项目上卡死。\n- 项目能整个搬进 WSL 的 `~/` 且构建密集 → 值得，编译测试全项最快。\n- 只是想跑 `make`、`gcc`、`rsync` → 值得，但记得项目也要在 ext4。\n- 其它情况 → 留在 Git Bash。\n\n**用 WSL 时必须知道的两件事：**\n\n```bash\n# 1) 不要用 wsl.exe -- bash -c '<脚本>' 传复杂脚本\n#    wsl.exe 会用 WSL 登录环境预展开变量，脚本内定义的变量被吞成空，且退出码仍为 0\nwsl.exe -d Ubuntu -- bash -c 'i=3; echo \"$((i+1))\"'   # → 1（错误数字，无报错）\n\n# 正确：走 stdin\nwsl.exe -d Ubuntu -- bash -s <<'EOF'\ni=3; echo \"$((i+1))\"                                   # → 4\nEOF\n\n# 2) 命令先落盘再取退出码，别指望行内 echo\n#    进度条的回车符经 wsl.exe 回传时会互相覆盖，echo $? 整行可能消失\nwsl.exe -d Ubuntu -- bash -s <<'EOF'\nnpx vitest run > /tmp/t.log 2>&1; echo \"EXIT=$?\"; tail -6 /tmp/t.log\nEOF\n```\n\n另外：**git worktree 在 WSL 里完全不可用**——`.git` 文件里存的是 `D:/...` 盘符路径，Linux 的 git 解析不了，直接 fatal。\n\nFile v5.0.0:CHANGELOG.md\n\n# windows-shell 更新日志\n\n版本号与 `SKILL.md` frontmatter 的 `version` 严格一致，由测试看守；\n发布脚本按版本号从本文件提取对应段落作为 changelog。\n\n## 5.0.0\n\n结构性变更：改为**按需展开**，并把 `windows-shell-routing` 合并进来。\n\n起因是一组 A/B 实测。四臂各跑 4 次同一个 Windows 任务（16 次运行），结论有两条：\n\n- **skill 的作用是精确的，不是普遍的。** 16 次里唯一 100% 分离的指标是「参数被静默改写」\n  这一步——无 skill 组 0/4 一次通过，读了规范的三组 12/12 全部一次通过。其余步骤靠常识\n  也能过，测不出差别。\n- **篇幅不等于价值。** 只读 10KB routing 的一组，总 token 是无 skill 组的 1.09 倍；\n  只读 18KB windows-shell 的一组是 1.43 倍、耗时 1.31 倍——而两组在那个关键步骤上\n  效果完全相同。多出来的 8KB 没有兑现任何行为差异。\n\n所以把一次性全量加载改成按需加载：\n\n- `SKILL.md` 缩到 138 行 / 5.8KB，只保留实测中真正拉开差距的内容：两类问题的判别、\n  shell 选型速查、五条高频规则、一次性环境配置，以及一张「遇到什么读哪个」的索引表。\n- 细节移入 `references/`（25KB，5 个文件）：`encoding.md`、`msys2.md`、\n  `shell-routing.md`、`gitbash-pitfalls.md`、`wsl.md`。规则原文一字未改，只是换了位置。\n- **默认加载量降到原来的 20%**（28.3KB → 5.8KB），完整信息量不减。\n\n合并 `windows-shell-routing`：该技能的全部内容进入 `references/shell-routing.md`、\n`wsl.md`、`gitbash-pitfalls.md`，选型速查表上浮到主文件第二节。之所以能合并，正是因为\n有了按需加载——此前拒绝合并的理由是「两者相加 527 行太长」，那个理由现在不成立了。\n原 slug 走 ClawHub 重定向。\n\n测试相应增加渐进式披露的守卫：主文件体积上限、references 链接必须可解析、不得有孤儿\n文件、以及七个「逃生开关」必须存在于 bundle 中的某处（它们是实测中真正改变了 agent\n行为的部分）。\n\n**发布前做了效果验证，并据此回填了两条。** 首版拆分后重跑同一任务，发现第 1 步\n（GBK 遗留文件转码）的一次通过率从 4/4 掉到 1/4——四个 agent 都正确判出了 GBK，却有\n三个先去试 `iconv`，撞上「Git Bash 没有 iconv」；那条提示被我移进了 references，\n主文件只剩一个指针。同时有三个 agent 点名想查「PS 5.1 怎么写无 BOM 的 UTF-8」，\n主文件只警告了陷阱、没给配方。\n\n于是把这两条回填主文件（新增第 4 条「Git Bash 少几个你以为有的工具」，并在第 3 条\n补上 `WriteAllText` + `UTF8Encoding($false)` 的写法），主文件从 5.8KB 到 6.4KB。\n重跑验证：第 1 步回到 4/4，命令数 11.2（六臂最低），总 token 相对无规范 0.87x\n——**是所有方案里唯一比不用规范还便宜的**。相对拆分前的 18KB 全量版：\ntoken 0.60x、耗时 0.54x、命令 0.71x。\n\n跨模型交叉验证（经腾讯 TokenHub 调 deepseek-v3.2 / v4-flash / v4-pro / kimi-k3 /\nminimax-m3 五个模型，各 6 道知识探针）：回填后「Git Bash 有无 iconv」一题从 1/5\n修正到 5/5。另有一条稳定的发现——`MSYS_NO_PATHCONV` 这个解法，五个模型两轮共 10 次\n裸问**没有一次答对**，而给了规范后 5/5 全对。模型知道参数会被改写，却不知道怎么解决；\n这正是本技能存在的意义所在。\n\n**一个诚实的限制**：两轮共 8 次运行中，agent 读取 references 的次数是 **0**，\n全部自评「主文件够用」。所以当前成立的其实是「主文件压缩到够用 + 附录供人查阅」，\n而不是 agent 会自己按指针去取。今后往 references 放内容需按此前提判断：\n凡是 agent 真正需要的，必须留在主文件里。\n\n## 4.4.0\n\n新增 MSYS2 参数改写规则，并修正三处经复测证伪的旧结论。稳定性结论均为 12 次采样，\n不再是单次观察。\n\n修正：\n\n- **pwsh 7 不再标注「输出可能乱码（实测不稳定）」**。实测 12/12 稳定 UTF-8。\n  UTF-8 前缀只对 PS 5.1 必需；外部程序（node/python）的输出穿过 PowerShell 不会被改，\n  两侧都不受影响。规则 1 改为一张按「中文来源 × 是否加前缀」划分的实测表。\n- **`reg query` 移出编码禁用表**。它的失败是 MSYS2 把注册表路径当 Unix 路径改写\n  （报「无效语法」而非乱码），加 `MSYS_NO_PATHCONV=1` 后原命令即可正常工作，与编码无关。\n  规则 3 因此拆为 A 类（真编码问题：wmic/systeminfo/ipconfig/netstat/tasklist/net user）\n  与 B 类（参数改写：reg query/findstr/schtasks），两类解法完全不同。\n- **规则 4 补上前提**。配好用户级 `PYTHONUTF8` 后裸 `python -c` 已经正常；\n  `-X utf8` 的价值在于不依赖环境（CI、容器、别人的机器），而非「不加必乱码」。\n  附反证：清空该变量后 `getpreferredencoding` 立刻退回 `cp936`。\n\n新增（原规则 6/7/8 顺延为 8/9/10）：\n\n- **规则 6：MSYS2 会改写以 `/` 开头的参数**。`/api/v1/users` 被改写成\n  `D:/Program Files/Git/api/v1/users`，`/S /C` 变成 `S:/ C:/`，Docker 的 `-v` 参数被吃掉。\n  最坏的是它**静默生效**——不报错、退出码正常、参数已经变了。给出\n  `MSYS_NO_PATHCONV` / `MSYS2_ARG_CONV_EXCL` / 双斜杠三种解法，并说明为什么不能全局导出\n  （会让 `/c/Users/...` 这类本该转换的参数也不转）。\n- **规则 7：`ln -s` 默认产出普通文件副本**，影响 pnpm workspace / npm link；\n  `MSYS=winsymlinks:nativestrict` 可修，附开发者模式检查命令。\n\n另新增开头的「两类问题，别混为一谈」判别小节（乱码 → 编码；语法错/找不到文件 → 参数改写），\n并在「不需要包装的工具」白名单下注明：输出编码干净 ≠ 没坑。\n\n## 4.3.0\n\n修正「一键配置」那行：原文写的 `npx win-encoding-fix install --setup-env` 从来没能工作过\n——该包从未发布到 npm，且 npx 解析的是包名而不是 bin 名。改为从仓库执行\n`node bin/cli.js setup-env`。仓库已重构为 skill-factory（Skill 工厂）多技能布局，\n本技能现位于 `skills/windows-shell/`；ClawHub slug、安装目录名与 frontmatter 的 name\n仍然都是 `windows-shell`，未发生变化。bundle 内容现为 SKILL.md + CHANGELOG.md。\n编码规则正文无改动。\n\n## 4.2.0\n\n修复 setup-env 的 Windows 用户级环境变量根本没设成功的 bug（嵌套双引号被 cmd.exe 吞掉）；\nSKILL.md 补充 GBK 遗留文件读取、UTF-8 BOM、Out-File 默认 UTF-16、stdin/InputEncoding、\n原始字节工具等编码陷阱；CLI 支持多盘 OpenClaw、失败时退出非零、参数解析健壮化；\n测试全程隔离 HOME 并大幅提升覆盖。\n\nFile v5.0.0:skill-card.md\n\n## Description:\n\nProvides Windows command-line guidance for choosing Git Bash, PowerShell, or WSL and avoiding encoding, BOM, MSYS2 path-conversion, Python, Node.js, Git, and virtual environment pitfalls on Windows 10/11.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chenmo0414](https://clawhub.ai/user/chenmo0414)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agents working on Windows 10/11 use this skill to select the right shell and avoid common Git Bash/MSYS2, PowerShell encoding, WSL, Python, Node.js, Git, and virtual environment failures.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill may lead an agent to suggest user-level Windows environment variable changes or global Git configuration changes.\n\nMitigation: Review proposed setup commands before execution, especially on shared or managed Windows machines.\n\nRisk: Shell-selection guidance can affect command behavior, such as MSYS2 path conversion, PowerShell encoding, or WSL filesystem performance.\n\nMitigation: Apply commands with the narrowest practical scope and prefer one-command shell switches instead of changing the whole session.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/chenmo0414/skills/windows-shell)\n- [Skill homepage](https://github.com/Chenmo0414/win-encoding-fix)\n- [Encoding details](references/encoding.md)\n- [MSYS2 path conversion and symlinks](references/msys2.md)\n- [Shell routing](references/shell-routing.md)\n- [Git Bash pitfalls](references/gitbash-pitfalls.md)\n- [WSL guidance](references/wsl.md)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Markdown, Shell commands, Configuration, Code]\n\n**Output Format:** [Markdown guidance with inline shell, PowerShell, Python, and JavaScript code blocks]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May recommend user-level Windows environment variables and global Git configuration changes for encoding consistency.]\n\n## Skill Version(s):\n\n5.0.0 (source: SKILL.md frontmatter and server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v4.4.0: 4 files, 12114 bytes\n\nFiles: CHANGELOG.md (3232b), skill-card.md (2342b), SKILL.md (18400b), _meta.json (132b)\n\nFile v4.4.0:SKILL.md\n\n---\nname: windows-shell\nversion: 4.4.0\ndescription: \"Windows 命令行编码与兼容性规范。覆盖 GBK/UTF-8 编码、MSYS2 参数路径转换、PowerShell/pwsh 互操作、Python/Node.js、Git 配置、代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。\"\nlicense: MIT\nmetadata:\n  openclaw:\n    emoji: \"🪟\"\n    os: [windows]\n    homepage: \"https://github.com/Chenmo0414/win-encoding-fix\"\n---\n\n# Windows 命令行编码规范\n\n用户系统：Windows 10/11（代码页 GBK/936），终端：MSYS2/Git Bash。以下规则均在真实 GBK 环境逐条实测验证；涉及稳定性判断的结论均为多次采样结果，而非单次观察。\n\n## 两类问题，别混为一谈\n\n在 Git Bash 里执行命令失败，绝大多数是下面两个原因之一。**先分清是哪一类，再套对应的解法**：\n\n**一、编码问题（输出乱码）** — 终端按 **UTF-8** 解码字节流，但 Windows 原生程序（PowerShell 5.1、CMD 工具、默认 Python）按 **GBK/936** 输出中文。字节被错误解码 → 乱码（如 `涓枃`、`M-DM-c`）。修复 = 让源头输出 UTF-8。\n\n**二、MSYS2 参数改写（命令报语法错，或参数悄悄变了）** — MSYS2 会把命令行里以 `/` 开头的参数当成 Unix 路径，自动转换成 Windows 路径再传给程序。修复 = `MSYS_NO_PATHCONV=1`（见规则 6）。\n\n判别方法：报错是「无效语法 / invalid / 找不到文件」而非乱码 → 多半是第二类。乱码 → 第一类。两类同时中招也很常见（报错信息本身是 GBK 的语法错误）。\n\n## 快速参考\n\n| 场景 | 做法 |\n|------|------|\n| 执行 PowerShell 命令 | `powershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; ...'` |\n| PowerShell 中有 `$_`/`$null` | 外层用**单引号**，防止 bash 展开 |\n| PowerShell 读文件 | `-Encoding` 必须匹配文件真实编码：UTF-8 文件用 `UTF8`；**GBK 遗留文件**用 `Default`/`oem`（别硬套 UTF8） |\n| PowerShell 写文件（无 BOM） | PS5.1 的 `-Encoding UTF8` 会**带 BOM**；无 BOM 需 `[System.IO.File]::WriteAllText` + `UTF8Encoding($false)` 或 pwsh `utf8NoBOM` |\n| PowerShell 输出重定向到文件 | PS5.1 的 `>`/`Out-File` 默认 **UTF-16 LE**；要 UTF-8 须显式 `Out-File -Encoding utf8` |\n| 管道把 UTF-8 **喂进** PowerShell | 还需设 `[Console]::InputEncoding`；PS→原生命令管道由 `$OutputEncoding` 决定 |\n| 传以 `/` 开头的参数 | 前置 `MSYS_NO_PATHCONV=1`，否则被改写成 Windows 路径（见规则 6） |\n| 建符号链接（pnpm workspace） | 设 `MSYS=winsymlinks:nativestrict`，否则 `ln -s` 产出的是副本（见规则 7） |\n| 执行系统查询 | 用 `Get-CimInstance` 替代 `wmic` |\n| 执行 Python 单行命令 | 加 `-X utf8`：`python -X utf8 -c \"...\"`（**不要假设** `PYTHONUTF8` 已生效） |\n| 生成 Python 代码 | `open()` 必须带 `encoding='utf-8'` |\n| Node.js 调系统命令 | execSync 中用 PowerShell 包装 |\n| Git 中文文件名乱码 | 确认 `core.quotepath=false` |\n| 传统 CMD 工具 | **禁止直接使用**，全部走 PowerShell |\n\n## 环境自检（开工前可选执行）\n\n判断当前 shell 的编码是否已正确配置：\n\n```bash\npython -c \"import sys; print('utf8_mode=', sys.flags.utf8_mode)\"   # 期望 1；为 0 说明 Python 默认 GBK\necho \"PYTHONUTF8=$PYTHONUTF8\"                                       # 期望 1；为空说明环境变量未加载\n```\n\n**关键认知**：`PYTHONUTF8` 等变量若只写在 `~/.bash_profile`，**非登录 / 非交互 shell 不会加载它**（AI 助手与脚本通常正是这种 shell）。因此：\n\n- 持久生效请配置 **Windows 用户级环境变量**（被所有进程继承，重启终端后生效）；\n- 当前会话内最可靠的做法是**每条命令显式带编码参数**（见下方各规则）。\n\n## 环境前置条件（持久配置，建议一次性执行）\n\n```bash\n# 1) Windows 用户级环境变量 —— 最可靠，所有进程继承（重启终端后生效）\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8;\n  [Environment]::SetEnvironmentVariable(\"PYTHONUTF8\", \"1\", \"User\");\n  [Environment]::SetEnvironmentVariable(\"PYTHONIOENCODING\", \"utf-8\", \"User\")'\n\n# 2) bash 显示相关变量（登录 shell 用），并让 .bashrc 也加载，覆盖非登录交互 shell\ncat >> ~/.bash_profile <<'EOF'\nexport PYTHONUTF8=1\nexport PYTHONIOENCODING=utf-8\nexport LANG=en_US.UTF-8\nexport LESSCHARSET=utf-8\nEOF\ngrep -q 'bash_profile' ~/.bashrc 2>/dev/null || echo '[ -f ~/.bash_profile ] && . ~/.bash_profile' >> ~/.bashrc\n\n# 3) Git 全局配置\ngit config --global core.quotepath false        # 中文文件名正常显示\ngit config --global core.autocrlf input         # 提交 LF，检出保持原样\ngit config --global i18n.commitEncoding utf-8    # commit 消息 UTF-8\ngit config --global i18n.logOutputEncoding utf-8\ngit config --global core.pager \"less -R\"\n```\n\n> 一键配置：在 [skill-factory](https://github.com/Chenmo0414/win-encoding-fix) 仓库里执行 `node bin/cli.js setup-env`\n\n## Shell 命令规则\n\n### 规则 1：PowerShell 命令必须加 UTF-8 前缀 + 外层单引号\n\n```bash\n# 标准模板（外层单引号 + UTF-8 前缀）\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; 你的命令'\n```\n\n**两个要点必须同时满足：**\n- `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8` — 不加则中文输出乱码\n- 外层**单引号** — 防止 bash 把 `$_`、`$null` 当作 bash 变量展开\n\n仅当命令中不含 `$` 变量时才可用外层双引号。\n\n**前缀到底什么时候必需**（v4.3.0 实测，各采样 12 次，结果完全稳定）：\n\n| 中文的来源 | PS 5.1 无前缀 | PS 5.1 加前缀 | pwsh 7 无前缀 |\n|------|------|------|------|\n| PowerShell 自己产出（`Write-Output`、cmdlet 结果） | **GBK ×12 → 乱码** | UTF-8 ×12 ✅ | **UTF-8 ×12 ✅** |\n| 外部程序产出（`node -e`、`python` 等） | UTF-8 ×12 ✅ | UTF-8 ×12 ✅ | UTF-8 ×12 ✅ |\n\n- **PS 5.1 必须加前缀**：只要中文由 PowerShell 自己产出，不加就是稳定乱码，没有侥幸。\n- **pwsh 7 不需要前缀**：实测 12/12 稳定 UTF-8。加了无害，脚本要兼容 5.1 时统一加是合理的，但不必因为「怕 pwsh 不稳」而加。\n- **外部程序的输出不受影响**：`node`/`git`/`python` 自己写 UTF-8 到 stdout，穿过 PowerShell 不会被改。所以「PS 包装」只对遵守控制台代码页的 Windows 原生工具才有意义（见规则 3）。\n\n### 规则 2：PowerShell 读写文件 —— `-Encoding` 必须匹配文件真实编码\n\n**读 UTF-8 文件**：PowerShell 5.1 不加 `-Encoding UTF8` 会用 GBK 读取，实测 `中文` → `涓枃`。\n\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Content \"path\\file.txt\" -Encoding UTF8'\n```\n\n**⚠️ 读 GBK 遗留文件（本机最常见）**：反过来，对一个真正的 GBK/936 文件强加 `-Encoding UTF8` 会**读出乱码**。`-Encoding` 的值必须等于文件的真实编码：\n\n| 文件真实编码 | PS 5.1 读法 | pwsh 7 读法 |\n|------|------|------|\n| UTF-8 | `-Encoding UTF8` | 默认即可（或 `-Encoding utf8`） |\n| GBK/936（遗留） | `-Encoding Default` 或不加 | `-Encoding oem` 或 `[System.Text.Encoding]::GetEncoding(936)` |\n\npwsh 7 默认按 UTF-8 读，遇到 GBK 文件反而会 mojibake，此时**必须显式指定 936**。\n\n**写文件的 BOM 陷阱**：PS 5.1 的 `Set-Content -Encoding UTF8` / `Out-File -Encoding UTF8` 会写入 **UTF-8 BOM**（`EF BB BF`），很多工具（旧编译器、某些 JSON 解析器、shell 脚本）会因此报错。要写**无 BOM** UTF-8：\n\n```powershell\n# PS 5.1 无 BOM 写法\n[System.IO.File]::WriteAllText(\"out.txt\", $content, (New-Object System.Text.UTF8Encoding($false)))\n# pwsh 7\nSet-Content out.txt -Value $content -Encoding utf8NoBOM\n```\n\n**输出重定向的编码**：PS 5.1 的 `>` 和 `Out-File` **默认写 UTF-16 LE**，不是 UTF-8。若要把命令输出存成 UTF-8 文件给后续读取，务必显式 `... | Out-File -Encoding utf8 out.txt`（注意上面的 BOM 说明），或捕获字符串后用 .NET 写。\n\n**stdin / 管道方向**：`[Console]::OutputEncoding` 只管 PowerShell **输出**。若要把 UTF-8 内容通过管道**喂进** PowerShell（`echo ... | powershell ...`），还需 `[Console]::InputEncoding = [System.Text.Encoding]::UTF8`；而 PowerShell **管道给下游原生命令**（如 `... | findstr`）用的是 `$OutputEncoding` 变量（默认 ASCII，会丢中文）。能用内联 `-Command` 参数就别走 stdin 管道。\n\n### 规则 3：禁止直接使用传统 CMD 工具和 cmd /c\n\n传统 CMD 工具多数输出 GBK 或 UTF-16，在 UTF-8 终端中乱码。`cmd /c` 同样不可用——`chcp 65001` 无法修复子进程编码（实测 `cmd /c \"chcp 65001 & echo 你好\"` 仍乱码）。\n\n但**并非全都是编码问题**。实测把它们分成了两类，解法完全不同：\n\n**A 类 —— 真·编码问题**（实测输出 GBK 字节，PS 包装可解决）：\n\n| 禁止 | 替代 |\n|------|------|\n| `wmic` | `Get-CimInstance` |\n| `systeminfo` | `Get-ComputerInfo` 或 PS 包装 `systeminfo` |\n| `ipconfig` | `Get-NetIPAddress` / `Get-NetIPConfiguration` |\n| `netstat` | `Get-NetTCPConnection` |\n| `tasklist` | `Get-Process` |\n| `net user` | `Get-LocalUser` |\n| `sc query` | `Get-Service`（英文输出时不乱码，但中文服务名会） |\n| `cmd /c` | **永远不用** |\n\n**B 类 —— 其实是 MSYS2 参数改写，不是编码问题**（实测：加 `MSYS_NO_PATHCONV=1` 后原命令即可正常工作）：\n\n| 命令 | 默认失败表现 | 真实原因 |\n|------|------|------|\n| `reg query \"HKCU\\Environment\"` | `错误: 无效语法。` | 注册表路径被当成 Unix 路径改写 |\n| `findstr 中文 /tmp/x.txt` | `FINDSTR: 无法打开 C:x.txt` | `/tmp/x.txt` 被改写成 `C:x.txt` |\n| `schtasks /query /tn \"\\...\"` | 参数错误 | 同上 |\n\nB 类仍然**建议**换成 `Get-ItemProperty` / `Select-String` / `Get-ScheduledTask`——PowerShell 版本输出更结构化、也不受 MSYS2 影响。但要知道：**它们不是「因为乱码」才被禁的**，误诊会让你在别处用错解法（比如给一个路径被改写的命令拼命加编码前缀，怎么加都不好使）。\n\n在 PowerShell 中包装传统命令**通常**可正确转码：\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; systeminfo | Select-Object -First 5'\n```\n\n> **注意，包装不是万能的**：`[Console]::OutputEncoding` 只对**遵守控制台输出代码页**的工具有效（`systeminfo`、`ipconfig` 等）。对于**输出固定 GBK 字节或原始字节**的工具（部分第三方 CLI、某些日志），包装后仍是乱码——这类需要「先按 936 解码、再转 UTF-8」：`powershell -Command '$s = (& some.exe) ; [Console]::OutputEncoding = [System.Text.Encoding]::UTF8; [System.Text.Encoding]::GetEncoding(936).GetString(...)'`，或在 Node/Python 侧以**字节**捕获再按真实编码解码（见规则 5、规则 9）。\n\n### 规则 4：Python 命令行执行 —— 优先 `-X utf8`，不要假设环境\n\n实测：AI 助手与脚本运行在**非交互 shell**，若 `PYTHONUTF8` 只写在 `~/.bash_profile`，它不会被加载，`sys.flags.utf8_mode` 为 0，`python -c \"print('你好')\"` 直接乱码。\n\n**注意前提**：一旦按上文「环境前置条件」把 `PYTHONUTF8` 配成了 **Windows 用户级环境变量**，裸 `python -c \"print('你好')\"` 就已经正常了（实测 `utf8_mode=1`、`getpreferredencoding=utf-8`）。所以 `-X utf8` 的价值不是「不加就一定乱码」，而是**不依赖环境是否配好**——在别人的机器、CI、容器里同样成立。这也正是它值得默认带上的理由。\n\n反证：把 `PYTHONUTF8` 清空后再测，`getpreferredencoding` 立刻退回 `cp936`。环境配置是会失效的，代码里的显式声明不会。\n\n**最可靠做法 —— 单行命令显式带 `-X utf8`：**\n```bash\npython -X utf8 -c \"print('你好世界')\"\n# 或临时设环境变量\nPYTHONUTF8=1 python script.py\n```\n\n`-X utf8` 同时让 `print()` 输出与 `open()` 默认读写都走 UTF-8，幂等无副作用，已是 UTF-8 环境时加它也不会出错。**生成代码时**仍应显式写 `encoding='utf-8'`（见规则 8），不依赖运行时标志。\n\n### 规则 5：Node.js 子进程调用系统命令\n\nNode.js 自身输出 UTF-8 没问题，但 `execSync`/`exec`/`spawn` 调用传统 CMD 工具时，输出是 GBK，`toString('utf-8')` 会乱码。\n\n**修复**：让子进程通过 PowerShell 输出 UTF-8：\n```javascript\nexecSync('powershell -Command \"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; systeminfo\"').toString('utf-8')\n```\n\n对于**输出原始 GBK 字节、不认控制台代码页**的工具，PowerShell 包装无效，应以字节捕获再手动解码：\n```javascript\nconst { execSync } = require('child_process')\nconst buf = execSync('some-gbk-tool.exe')       // 拿 Buffer，不要直接 toString\nconst text = new TextDecoder('gbk').decode(buf)  // 按真实编码解码\n```\n\n### 规则 6：MSYS2 会改写以 `/` 开头的参数\n\nGit Bash（MSYS2）在把参数交给 **非 MSYS2 程序**（即所有 Windows 原生 .exe）之前，会把看起来像 Unix 路径的参数自动转换成 Windows 路径。这是 MSYS2 的设计，不是 bug——但它**静默生效**，不报错、退出码正常，参数已经变了。\n\n```bash\nnode app.js /api/v1/users\n# 程序实际收到：D:/Program Files/Git/api/v1/users   ← 前面被拼上了 Git 安装目录\n\nprog /S /C                  # → 变成  S:/ C:/\ndocker run -v /app:/app ... # → -v 后面的参数被破坏\nreg query \"HKCU\\Environment\"   # → 错误: 无效语法。\nfindstr 中文 /tmp/x.txt        # → FINDSTR: 无法打开 C:x.txt\n```\n\n**什么时候会中招**：参数以 `/` 开头，且接收方是 Windows 原生程序。典型场景——REST 路径、Docker 卷映射、Windows 风格开关（`/S` `/C` `/query`）、注册表路径、传给 `.exe` 的 Unix 路径。\n\n**三种解法**（均实测有效）：\n\n```bash\n# A. 单条命令临时关闭（推荐，作用域最小）\nMSYS_NO_PATHCONV=1 reg query \"HKCU\\Environment\" /v PYTHONUTF8\nMSYS_NO_PATHCONV=1 node app.js /api/v1/users\n\n# B. 按参数排除\nMSYS2_ARG_CONV_EXCL='*' node app.js /api/v1/users\n\n# C. 双斜杠转义（只想保护单个参数时）\nnode app.js //api/v1/users\n```\n\n**不要全局导出 `MSYS_NO_PATHCONV=1`**：关掉转换后，`/c/Users/...` 这类你确实希望被转成 `C:\\Users\\...` 的参数也不再转换，会引入另一批问题。按需在单条命令前加。\n\n> 与编码问题的区别：编码问题表现为**乱码**，参数改写表现为**语法错/找不到文件/行为不对但不报错**。诊断时先看报错形态，别拿编码的解法去治路径的病。\n\n### 规则 7：Git Bash 的 `ln -s` 默认产出的是副本\n\n```bash\nln -s t.txt l.txt && ls -l l.txt\n# 默认：  -rw-r--r--  ← 普通文件副本，不是链接\n```\n\n对普通脚本无所谓，但 **pnpm workspace、npm link、monorepo 的本地依赖都依赖真符号链接**，退化成副本会导致改了源码却不生效、或磁盘占用异常。\n\n```bash\n# 修复：产出真正的符号链接（lrwxrwxrwx）\nexport MSYS=winsymlinks:nativestrict\nln -s t.txt l.txt && ls -l l.txt      # → lrwxrwxrwx ... l.txt -> t.txt\n```\n\nWindows 10/11 需先启用**开发者模式**（设置 → 隐私和安全性 → 开发者选项），否则创建符号链接要管理员权限。检查是否已启用：\n\n```bash\npowershell -NoProfile -Command '(Get-ItemProperty \"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock\").AllowDevelopmentWithoutDevLicense'\n# 返回 1 = 已启用\n```\n\n## 代码生成规则\n\nAI 生成代码时必须遵循以下规则，确保产出的代码在 Windows 上编码正确。\n\n### 规则 8：Python 文件 I/O 必须指定编码\n\n```python\n# 正确 — 显式指定 encoding\nwith open('data.txt', 'r', encoding='utf-8') as f:\n    content = f.read()\n\nwith open('output.txt', 'w', encoding='utf-8') as f:\n    f.write(content)\n\n# 错误 — 裸 open() 在 Windows 上默认 GBK（实测 locale.getpreferredencoding() = cp936）\nwith open('data.txt', 'r') as f:  # 不要这样写\n    content = f.read()\n```\n\n同样适用于 `json.load`/`json.dump`、`csv.reader`、`pathlib.Path.read_text()` 等需要文件对象的场景。\n\nPython subprocess 调用系统命令时也需注意编码：\n```python\nimport subprocess\nresult = subprocess.run(\n    ['powershell', '-Command', '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Process'],\n    capture_output=True, text=True, encoding='utf-8'\n)\n```\n\n### 规则 9：Node.js 文件操作和子进程编码\n\n```javascript\n// 文件读写 — 显式指定 utf-8\nfs.readFileSync('data.txt', 'utf-8')\nfs.writeFileSync('output.txt', content, 'utf-8')\n\n// 子进程调用 Windows 原生命令 — 通过 PowerShell 包装\nconst { execSync } = require('child_process')\nconst output = execSync(\n  'powershell -Command \"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Service\"'\n).toString('utf-8')\n```\n\n### 规则 10：Git 中文支持\n\n环境已配置 `core.quotepath=false`，中文文件名在 `git status`/`git diff` 中正常显示。\n\n如果发现中文文件名仍显示为 `\\346\\265\\213\\350\\257\\225` 形式，执行：\n```bash\ngit config --global core.quotepath false\n```\n\n## 格式化技巧\n\n- 宽表格加 `| Out-String -Width 200` 防截断\n- `Format-Table -AutoSize` 自适应列宽\n- `Format-List` 展示详细单条记录\n- `Select-Object` 控制返回字段数量\n\n## 不需要包装的工具\n\n以下工具本身输出 UTF-8，可直接使用：\n- `git`、`node`、`npm`、`pnpm`、`bun`、`cargo`、`go`\n- bash 内置：`echo`、`cat`、`ls`、`grep` 等\n- `python`：加 `-X utf8` 后可直接使用（见规则 4）\n\n> **编码没问题 ≠ 完全没坑**：这些工具的**输出编码**是干净的，但只要给它们传以 `/` 开头的参数，\n> 仍会被 MSYS2 改写（见规则 6）；`pnpm` 的 workspace 还依赖真符号链接（见规则 7）。\n> 两件事互相独立，别因为「这个工具在白名单里」就放松警惕。\n\nFile v4.4.0:_meta.json\n\n{\n  \"ownerId\": \"kn78ryxatfm99gvwnvgexh8hkx847bk7\",\n  \"slug\": \"windows-shell\",\n  \"version\": \"4.4.0\",\n  \"publishedAt\": 1787125745865\n}\n\nFile v4.4.0:CHANGELOG.md\n\n# windows-shell 更新日志\n\n版本号与 `SKILL.md` frontmatter 的 `version` 严格一致，由测试看守；\n发布脚本按版本号从本文件提取对应段落作为 changelog。\n\n## 4.4.0\n\n新增 MSYS2 参数改写规则，并修正三处经复测证伪的旧结论。稳定性结论均为 12 次采样，\n不再是单次观察。\n\n修正：\n\n- **pwsh 7 不再标注「输出可能乱码（实测不稳定）」**。实测 12/12 稳定 UTF-8。\n  UTF-8 前缀只对 PS 5.1 必需；外部程序（node/python）的输出穿过 PowerShell 不会被改，\n  两侧都不受影响。规则 1 改为一张按「中文来源 × 是否加前缀」划分的实测表。\n- **`reg query` 移出编码禁用表**。它的失败是 MSYS2 把注册表路径当 Unix 路径改写\n  （报「无效语法」而非乱码），加 `MSYS_NO_PATHCONV=1` 后原命令即可正常工作，与编码无关。\n  规则 3 因此拆为 A 类（真编码问题：wmic/systeminfo/ipconfig/netstat/tasklist/net user）\n  与 B 类（参数改写：reg query/findstr/schtasks），两类解法完全不同。\n- **规则 4 补上前提**。配好用户级 `PYTHONUTF8` 后裸 `python -c` 已经正常；\n  `-X utf8` 的价值在于不依赖环境（CI、容器、别人的机器），而非「不加必乱码」。\n  附反证：清空该变量后 `getpreferredencoding` 立刻退回 `cp936`。\n\n新增（原规则 6/7/8 顺延为 8/9/10）：\n\n- **规则 6：MSYS2 会改写以 `/` 开头的参数**。`/api/v1/users` 被改写成\n  `D:/Program Files/Git/api/v1/users`，`/S /C` 变成 `S:/ C:/`，Docker 的 `-v` 参数被吃掉。\n  最坏的是它**静默生效**——不报错、退出码正常、参数已经变了。给出\n  `MSYS_NO_PATHCONV` / `MSYS2_ARG_CONV_EXCL` / 双斜杠三种解法，并说明为什么不能全局导出\n  （会让 `/c/Users/...` 这类本该转换的参数也不转）。\n- **规则 7：`ln -s` 默认产出普通文件副本**，影响 pnpm workspace / npm link；\n  `MSYS=winsymlinks:nativestrict` 可修，附开发者模式检查命令。\n\n另新增开头的「两类问题，别混为一谈」判别小节（乱码 → 编码；语法错/找不到文件 → 参数改写），\n并在「不需要包装的工具」白名单下注明：输出编码干净 ≠ 没坑。\n\n## 4.3.0\n\n修正「一键配置」那行：原文写的 `npx win-encoding-fix install --setup-env` 从来没能工作过\n——该包从未发布到 npm，且 npx 解析的是包名而不是 bin 名。改为从仓库执行\n`node bin/cli.js setup-env`。仓库已重构为 skill-factory（Skill 工厂）多技能布局，\n本技能现位于 `skills/windows-shell/`；ClawHub slug、安装目录名与 frontmatter 的 name\n仍然都是 `windows-shell`，未发生变化。bundle 内容现为 SKILL.md + CHANGELOG.md。\n编码规则正文无改动。\n\n## 4.2.0\n\n修复 setup-env 的 Windows 用户级环境变量根本没设成功的 bug（嵌套双引号被 cmd.exe 吞掉）；\nSKILL.md 补充 GBK 遗留文件读取、UTF-8 BOM、Out-File 默认 UTF-16、stdin/InputEncoding、\n原始字节工具等编码陷阱；CLI 支持多盘 OpenClaw、失败时退出非零、参数解析健壮化；\n测试全程隔离 HOME 并大幅提升覆盖。\n\nFile v4.4.0:skill-card.md\n\n## Description:\n\nWindows command-line encoding and compatibility guidance for GBK/UTF-8 behavior, MSYS2 path conversion, PowerShell and pwsh interoperability, Python and Node.js usage, Git configuration, and code-generation rules on Windows 10/11 with MSYS2 or Git Bash.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chenmo0414](https://clawhub.ai/user/chenmo0414)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and engineers use this skill to diagnose and avoid Windows shell encoding, path-conversion, and interop issues when issuing commands or generating Python, Node.js, PowerShell, and Git workflows for Windows 10/11 with MSYS2 or Git Bash.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Optional setup commands can persistently change Windows user environment variables, shell startup files, and global Git configuration.\n\nMitigation: Review each persistent setting before applying it, especially on shared or managed machines, and prefer command-scoped encoding or path-conversion settings when broad changes are not needed.\n\nRisk: MSYS2 path conversion and Windows encoding behavior can silently alter arguments or produce misleading command output if the guidance is applied to the wrong failure mode.\n\nMitigation: Classify failures as encoding issues or path-conversion issues before applying fixes, and test commands in the target Windows shell environment.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/chenmo0414/skills/windows-shell)\n- [Project homepage](https://github.com/Chenmo0414/win-encoding-fix)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Shell commands, Code, Configuration]\n\n**Output Format:** [Markdown with inline shell, PowerShell, Python, and JavaScript examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Windows-focused guidance for command-line behavior, file encoding, environment variables, and Git configuration.]\n\n## Skill Version(s):\n\n4.4.0 (source: server release evidence, SKILL.md frontmatter, CHANGELOG.md)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v4.2.0: 5 files, 10044 bytes\n\nFiles: LICENSE (1063b), README.md (4752b), skill-card.md (2470b), SKILL.md (12195b), _meta.json (132b)\n\nFile v4.2.0:SKILL.md\n\n---\nname: windows-shell\nversion: 4.2.0\ndescription: \"Windows 命令行编码与兼容性规范。覆盖 GBK/UTF-8 编码、PowerShell/pwsh 互操作、Python/Node.js、Git 配置、代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。\"\nlicense: MIT\nmetadata:\n  openclaw:\n    emoji: \"🪟\"\n    os: [windows]\n    homepage: \"https://github.com/Chenmo0414/win-encoding-fix\"\n---\n\n# Windows 命令行编码规范\n\n用户系统：Windows 10/11（代码页 GBK/936），终端：MSYS2/Git Bash。以下规则均在真实 GBK 环境逐条实测验证。\n\n## 为什么会乱码（一句话原理）\n\n终端按 **UTF-8** 解码字节流，但 Windows 原生程序（PowerShell 5.1、CMD 工具、默认 Python）按 **GBK/936** 输出中文。字节被错误解码 → 乱码（如 `涓枃`、`M-DM-c`）。修复 = 让源头输出 UTF-8。\n\n## 快速参考\n\n| 场景 | 做法 |\n|------|------|\n| 执行 PowerShell 命令 | `powershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; ...'` |\n| PowerShell 中有 `$_`/`$null` | 外层用**单引号**，防止 bash 展开 |\n| PowerShell 读文件 | `-Encoding` 必须匹配文件真实编码：UTF-8 文件用 `UTF8`；**GBK 遗留文件**用 `Default`/`oem`（别硬套 UTF8） |\n| PowerShell 写文件（无 BOM） | PS5.1 的 `-Encoding UTF8` 会**带 BOM**；无 BOM 需 `[System.IO.File]::WriteAllText` + `UTF8Encoding($false)` 或 pwsh `utf8NoBOM` |\n| PowerShell 输出重定向到文件 | PS5.1 的 `>`/`Out-File` 默认 **UTF-16 LE**；要 UTF-8 须显式 `Out-File -Encoding utf8` |\n| 管道把 UTF-8 **喂进** PowerShell | 还需设 `[Console]::InputEncoding`；PS→原生命令管道由 `$OutputEncoding` 决定 |\n| 执行系统查询 | 用 `Get-CimInstance` 替代 `wmic` |\n| 执行 Python 单行命令 | 加 `-X utf8`：`python -X utf8 -c \"...\"`（**不要假设** `PYTHONUTF8` 已生效） |\n| 生成 Python 代码 | `open()` 必须带 `encoding='utf-8'` |\n| Node.js 调系统命令 | execSync 中用 PowerShell 包装 |\n| Git 中文文件名乱码 | 确认 `core.quotepath=false` |\n| 传统 CMD 工具 | **禁止直接使用**，全部走 PowerShell |\n\n## 环境自检（开工前可选执行）\n\n判断当前 shell 的编码是否已正确配置：\n\n```bash\npython -c \"import sys; print('utf8_mode=', sys.flags.utf8_mode)\"   # 期望 1；为 0 说明 Python 默认 GBK\necho \"PYTHONUTF8=$PYTHONUTF8\"                                       # 期望 1；为空说明环境变量未加载\n```\n\n**关键认知**：`PYTHONUTF8` 等变量若只写在 `~/.bash_profile`，**非登录 / 非交互 shell 不会加载它**（AI 助手与脚本通常正是这种 shell）。因此：\n\n- 持久生效请配置 **Windows 用户级环境变量**（被所有进程继承，重启终端后生效）；\n- 当前会话内最可靠的做法是**每条命令显式带编码参数**（见下方各规则）。\n\n## 环境前置条件（持久配置，建议一次性执行）\n\n```bash\n# 1) Windows 用户级环境变量 —— 最可靠，所有进程继承（重启终端后生效）\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8;\n  [Environment]::SetEnvironmentVariable(\"PYTHONUTF8\", \"1\", \"User\");\n  [Environment]::SetEnvironmentVariable(\"PYTHONIOENCODING\", \"utf-8\", \"User\")'\n\n# 2) bash 显示相关变量（登录 shell 用），并让 .bashrc 也加载，覆盖非登录交互 shell\ncat >> ~/.bash_profile <<'EOF'\nexport PYTHONUTF8=1\nexport PYTHONIOENCODING=utf-8\nexport LANG=en_US.UTF-8\nexport LESSCHARSET=utf-8\nEOF\ngrep -q 'bash_profile' ~/.bashrc 2>/dev/null || echo '[ -f ~/.bash_profile ] && . ~/.bash_profile' >> ~/.bashrc\n\n# 3) Git 全局配置\ngit config --global core.quotepath false        # 中文文件名正常显示\ngit config --global core.autocrlf input         # 提交 LF，检出保持原样\ngit config --global i18n.commitEncoding utf-8    # commit 消息 UTF-8\ngit config --global i18n.logOutputEncoding utf-8\ngit config --global core.pager \"less -R\"\n```\n\n> 一键配置：`npx win-encoding-fix install --setup-env`\n\n## Shell 命令规则\n\n### 规则 1：PowerShell 命令必须加 UTF-8 前缀 + 外层单引号\n\n```bash\n# 标准模板（外层单引号 + UTF-8 前缀）\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; 你的命令'\n```\n\n**两个要点必须同时满足：**\n- `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8` — 不加则中文输出乱码\n- 外层**单引号** — 防止 bash 把 `$_`、`$null` 当作 bash 变量展开\n\n仅当命令中不含 `$` 变量时才可用外层双引号。\n\n**关于 pwsh（PowerShell 7）**：若系统装有 `pwsh`（`which pwsh` 可检测），它读写文件默认即 UTF-8，但**输出到管道仍可能因控制台代码页而乱码**（实测不稳定）。因此 pwsh 同样建议带上述前缀——前缀对 pwsh 无害、对 5.1 必需，统一加最省心。\n\n### 规则 2：PowerShell 读写文件 —— `-Encoding` 必须匹配文件真实编码\n\n**读 UTF-8 文件**：PowerShell 5.1 不加 `-Encoding UTF8` 会用 GBK 读取，实测 `中文` → `涓枃`。\n\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Content \"path\\file.txt\" -Encoding UTF8'\n```\n\n**⚠️ 读 GBK 遗留文件（本机最常见）**：反过来，对一个真正的 GBK/936 文件强加 `-Encoding UTF8` 会**读出乱码**。`-Encoding` 的值必须等于文件的真实编码：\n\n| 文件真实编码 | PS 5.1 读法 | pwsh 7 读法 |\n|------|------|------|\n| UTF-8 | `-Encoding UTF8` | 默认即可（或 `-Encoding utf8`） |\n| GBK/936（遗留） | `-Encoding Default` 或不加 | `-Encoding oem` 或 `[System.Text.Encoding]::GetEncoding(936)` |\n\npwsh 7 默认按 UTF-8 读，遇到 GBK 文件反而会 mojibake，此时**必须显式指定 936**。\n\n**写文件的 BOM 陷阱**：PS 5.1 的 `Set-Content -Encoding UTF8` / `Out-File -Encoding UTF8` 会写入 **UTF-8 BOM**（`EF BB BF`），很多工具（旧编译器、某些 JSON 解析器、shell 脚本）会因此报错。要写**无 BOM** UTF-8：\n\n```powershell\n# PS 5.1 无 BOM 写法\n[System.IO.File]::WriteAllText(\"out.txt\", $content, (New-Object System.Text.UTF8Encoding($false)))\n# pwsh 7\nSet-Content out.txt -Value $content -Encoding utf8NoBOM\n```\n\n**输出重定向的编码**：PS 5.1 的 `>` 和 `Out-File` **默认写 UTF-16 LE**，不是 UTF-8。若要把命令输出存成 UTF-8 文件给后续读取，务必显式 `... | Out-File -Encoding utf8 out.txt`（注意上面的 BOM 说明），或捕获字符串后用 .NET 写。\n\n**stdin / 管道方向**：`[Console]::OutputEncoding` 只管 PowerShell **输出**。若要把 UTF-8 内容通过管道**喂进** PowerShell（`echo ... | powershell ...`），还需 `[Console]::InputEncoding = [System.Text.Encoding]::UTF8`；而 PowerShell **管道给下游原生命令**（如 `... | findstr`）用的是 `$OutputEncoding` 变量（默认 ASCII，会丢中文）。能用内联 `-Command` 参数就别走 stdin 管道。\n\n### 规则 3：禁止直接使用传统 CMD 工具和 cmd /c\n\n传统 CMD 工具输出 GBK 或 UTF-16，在 UTF-8 终端中全部乱码。`cmd /c` 同样不可用——`chcp 65001` 无法修复子进程编码（实测 `cmd /c \"chcp 65001 & echo 你好\"` 仍乱码）。\n\n**必须使用 PowerShell 替代：**\n\n| 禁止 | 替代 |\n|------|------|\n| `wmic` | `Get-CimInstance` |\n| `systeminfo` | `Get-ComputerInfo` 或 PS 包装 `systeminfo` |\n| `ipconfig` | `Get-NetIPAddress` / `Get-NetIPConfiguration` |\n| `netstat` | `Get-NetTCPConnection` |\n| `tasklist` | `Get-Process` |\n| `sc query` | `Get-Service` |\n| `reg query` | `Get-ItemProperty 'HKLM:\\...'` |\n| `net user` | `Get-LocalUser` |\n| `schtasks` | `Get-ScheduledTask` |\n| `findstr` | `Select-String` |\n| `cmd /c` | **永远不用** |\n\n在 PowerShell 中包装传统命令**通常**可正确转码：\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; systeminfo | Select-Object -First 5'\n```\n\n> **注意，包装不是万能的**：`[Console]::OutputEncoding` 只对**遵守控制台输出代码页**的工具有效（`systeminfo`、`ipconfig` 等）。对于**输出固定 GBK 字节或原始字节**的工具（部分第三方 CLI、某些日志），包装后仍是乱码——这类需要「先按 936 解码、再转 UTF-8」：`powershell -Command '$s = (& some.exe) ; [Console]::OutputEncoding = [System.Text.Encoding]::UTF8; [System.Text.Encoding]::GetEncoding(936).GetString(...)'`，或在 Node/Python 侧以**字节**捕获再按真实编码解码（见规则 5、规则 7）。\n\n### 规则 4：Python 命令行执行 —— 优先 `-X utf8`，不要假设环境\n\n实测：AI 助手与脚本运行在**非交互 shell**，`~/.bash_profile` 中的 `PYTHONUTF8` 不会被加载，`sys.flags.utf8_mode` 仍为 0，`python -c \"print('你好')\"` 直接乱码。\n\n**最可靠做法 —— 单行命令显式带 `-X utf8`：**\n```bash\npython -X utf8 -c \"print('你好世界')\"\n# 或临时设环境变量\nPYTHONUTF8=1 python script.py\n```\n\n`-X utf8` 同时让 `print()` 输出与 `open()` 默认读写都走 UTF-8，幂等无副作用，已是 UTF-8 环境时加它也不会出错。**生成代码时**仍应显式写 `encoding='utf-8'`（见规则 6），不依赖运行时标志。\n\n### 规则 5：Node.js 子进程调用系统命令\n\nNode.js 自身输出 UTF-8 没问题，但 `execSync`/`exec`/`spawn` 调用传统 CMD 工具时，输出是 GBK，`toString('utf-8')` 会乱码。\n\n**修复**：让子进程通过 PowerShell 输出 UTF-8：\n```javascript\nexecSync('powershell -Command \"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; systeminfo\"').toString('utf-8')\n```\n\n对于**输出原始 GBK 字节、不认控制台代码页**的工具，PowerShell 包装无效，应以字节捕获再手动解码：\n```javascript\nconst { execSync } = require('child_process')\nconst buf = execSync('some-gbk-tool.exe')       // 拿 Buffer，不要直接 toString\nconst text = new TextDecoder('gbk').decode(buf)  // 按真实编码解码\n```\n\n## 代码生成规则\n\nAI 生成代码时必须遵循以下规则，确保产出的代码在 Windows 上编码正确。\n\n### 规则 6：Python 文件 I/O 必须指定编码\n\n```python\n# 正确 — 显式指定 encoding\nwith open('data.txt', 'r', encoding='utf-8') as f:\n    content = f.read()\n\nwith open('output.txt', 'w', encoding='utf-8') as f:\n    f.write(content)\n\n# 错误 — 裸 open() 在 Windows 上默认 GBK（实测 locale.getpreferredencoding() = cp936）\nwith open('data.txt', 'r') as f:  # 不要这样写\n    content = f.read()\n```\n\n同样适用于 `json.load`/`json.dump`、`csv.reader`、`pathlib.Path.read_text()` 等需要文件对象的场景。\n\nPython subprocess 调用系统命令时也需注意编码：\n```python\nimport subprocess\nresult = subprocess.run(\n    ['powershell', '-Command', '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Process'],\n    capture_output=True, text=True, encoding='utf-8'\n)\n```\n\n### 规则 7：Node.js 文件操作和子进程编码\n\n```javascript\n// 文件读写 — 显式指定 utf-8\nfs.readFileSync('data.txt', 'utf-8')\nfs.writeFileSync('output.txt', content, 'utf-8')\n\n// 子进程调用 Windows 原生命令 — 通过 PowerShell 包装\nconst { execSync } = require('child_process')\nconst output = execSync(\n  'powershell -Command \"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Service\"'\n).toString('utf-8')\n```\n\n### 规则 8：Git 中文支持\n\n环境已配置 `core.quotepath=false`，中文文件名在 `git status`/`git diff` 中正常显示。\n\n如果发现中文文件名仍显示为 `\\346\\265\\213\\350\\257\\225` 形式，执行：\n```bash\ngit config --global core.quotepath false\n```\n\n## 格式化技巧\n\n- 宽表格加 `| Out-String -Width 200` 防截断\n- `Format-Table -AutoSize` 自适应列宽\n- `Format-List` 展示详细单条记录\n- `Select-Object` 控制返回字段数量\n\n## 不需要包装的工具\n\n以下工具本身输出 UTF-8，可直接使用：\n- `git`、`node`、`npm`、`pnpm`、`bun`、`cargo`、`go`\n- bash 内置：`echo`、`cat`、`ls`、`grep` 等\n- `python`：加 `-X utf8` 后可直接使用（见规则 4）\n\nFile v4.2.0:README.md\n\n# win-encoding-fix\n\nWindows Shell encoding skill for AI coding assistants. Fixes GBK/UTF-8 encoding issues on Windows 10+ with MSYS2/Git Bash.\n\nTested and verified on real Windows 10 (code page 936/GBK) environments.\n\n## Problem\n\nOn Windows with GBK locale, AI coding assistants (Claude Code, Codex, OpenClaw) frequently produce garbled Chinese output because:\n\n- PowerShell outputs GBK by default, but the terminal expects UTF-8\n- Traditional CMD tools (`wmic`, `systeminfo`, etc.) output UTF-16 or GBK\n- Python `print()` and `open()` default to GBK\n- Node.js `execSync` decodes GBK output as UTF-8\n- Git shows Chinese filenames as octal escapes\n\nThis skill teaches AI assistants to handle all these cases correctly.\n\n> **A subtle trap this skill solves:** exports written to `~/.bash_profile` are only sourced by *login* shells. AI assistants and scripts run in **non-interactive** shells that source neither `.bash_profile` nor `.bashrc`, so `PYTHONUTF8=1` set there never reaches the Python the agent actually runs (`sys.flags.utf8_mode` stays `0`). v4.1.0 fixes this by setting **Windows User-level environment variables** (inherited by every process) and by having `.bashrc` source `.bash_profile`.\n\n## What's Included\n\n- **8 encoding rules** covering PowerShell/pwsh, CMD, Python, Node.js, and Git\n- **Quick reference table** + an environment self-check\n- **Code generation rules** ensuring AI-written code handles encoding properly\n- **Robust environment setup** — Windows User env vars + bash rc files + git config\n\n## Install\n\n### ClawHub (recommended)\n\nPublished as [`windows-shell`](https://clawhub.dev) — install with the ClawHub CLI:\n\n```bash\nclawhub install windows-shell\n```\n\n### Manual\n\nCopy `SKILL.md` to whichever assistants you use:\n\n| Platform | Path |\n|----------|------|\n| Claude Code | `~/.claude/skills/windows-shell/SKILL.md` |\n| Codex | `~/.codex/skills/windows-shell/SKILL.md` |\n| OpenClaw | `~/.openclaw/workspace/skills/windows-shell/SKILL.md` |\n\nOr, from a clone of this repo, run the bundled installer (auto-detects all three):\n\n```bash\nnode bin/cli.js install --setup-env\n```\n\n### npm\n\n> **Not yet published to npm.** The `npx win-encoding-fix` / `npm install -g win-encoding-fix`\n> commands below will only work once the package is published to the npm registry.\n> Until then, use the ClawHub or manual install above.\n\n```bash\nnpx win-encoding-fix install --setup-env      # after npm publish\nnpm install -g win-encoding-fix               # after npm publish\n```\n\n## Commands\n\n```bash\nwin-encoding-fix install              # Install to auto-detected platforms\nwin-encoding-fix install --setup-env  # Also configure bash_profile + git\nwin-encoding-fix setup-env            # Only configure environment\nwin-encoding-fix uninstall            # Remove skill files\n\n# Custom install paths (if not using default locations)\nwin-encoding-fix install --claude=D:\\my-claude\nwin-encoding-fix install --codex=E:\\my-codex\nwin-encoding-fix install --openclaw=E:\\.openclaw\n```\n\n## Environment Setup\n\nThe `--setup-env` flag configures three layers so the fixes apply everywhere:\n\n**1. Windows User environment variables** (inherited by every process — the robust layer; takes effect after restarting the terminal):\n```\nPYTHONUTF8=1\nPYTHONIOENCODING=utf-8\n```\n\n**2. bash rc files** (for interactive Git Bash):\n```bash\n# ~/.bash_profile\nexport PYTHONUTF8=1\nexport PYTHONIOENCODING=utf-8\nexport LANG=en_US.UTF-8\nexport LESSCHARSET=utf-8\n# ~/.bashrc — so non-login shells get the same vars\n[ -f ~/.bash_profile ] && . ~/.bash_profile\n```\n\n**3. Git global config:**\n```bash\ngit config --global core.quotepath false        # Chinese filenames\ngit config --global core.autocrlf input         # LF on commit\ngit config --global i18n.commitEncoding utf-8\ngit config --global i18n.logOutputEncoding utf-8\ngit config --global core.pager \"less -R\"\n```\n\n## Rules Summary\n\n| # | Rule | Scope |\n|---|------|-------|\n| 1 | PowerShell/pwsh: UTF-8 prefix + single quotes | Shell |\n| 2 | PowerShell: `-Encoding UTF8` for file reads | Shell |\n| 3 | Never use legacy CMD tools or `cmd /c` | Shell |\n| 4 | Python: prefer `python -X utf8` (don't assume env is loaded) | Shell |\n| 5 | Node.js: PowerShell wrapper for `execSync` | Shell |\n| 6 | Python codegen: `open()` must have `encoding='utf-8'` | Code |\n| 7 | Node.js codegen: explicit `'utf-8'` in fs/child_process | Code |\n| 8 | Git: `core.quotepath=false` for Chinese filenames | Git |\n\n## Testing\n\n```bash\nnpm test    # runs node test/cli.test.js\n```\n\nThe suite covers install (custom paths, idempotency, content integrity), uninstall,\nhelp, unknown-command fallback, `setup-env` (rc files + git config, isolated from the\nreal environment), and SKILL.md frontmatter validity.\n\n## License\n\nMIT\n\nFile v4.2.0:_meta.json\n\n{\n  \"ownerId\": \"kn78ryxatfm99gvwnvgexh8hkx847bk7\",\n  \"slug\": \"windows-shell\",\n  \"version\": \"4.2.0\",\n  \"publishedAt\": 1784479437851\n}\n\nFile v4.2.0:skill-card.md\n\n## Description: <br>\nProvides Windows command-line encoding and compatibility guidance for GBK/UTF-8, PowerShell and pwsh, Python, Node.js, Git, and code generation on Windows 10/11 with MSYS2 or Git Bash. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[chenmo0414](https://clawhub.ai/user/chenmo0414) <br>\n\n### License/Terms of Use: <br>\nMIT <br>\n\n\n## Use Case: <br>\nDevelopers and coding agents use this skill to avoid garbled Windows shell output and to generate Python, Node.js, PowerShell, and Git commands that handle GBK and UTF-8 encoding correctly. It is most relevant for Windows 10/11 systems using MSYS2 or Git Bash. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Optional setup commands can persistently change Windows user environment variables, shell startup files, and global Git configuration. <br>\nMitigation: Review the setup commands before running them, apply them only to the intended Windows user account, and keep a plan to revert environment variables, ~/.bash_profile, ~/.bashrc, and global Git settings if they affect other tools. <br>\nRisk: Using the wrong encoding for existing files or tool output can still produce corrupted text or misleading command results. <br>\nMitigation: Confirm whether each file or tool emits UTF-8, GBK/936, UTF-16, or raw bytes before applying conversion guidance, and test changes in a non-critical shell or repository first. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/chenmo0414/skills/windows-shell) <br>\n- [Project homepage from ClawHub metadata](https://github.com/Chenmo0414/win-encoding-fix) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown guidance with inline shell, PowerShell, Python, and JavaScript examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Windows-specific guidance for command execution, file encoding, environment setup, and global Git configuration.] <br>\n\n## Skill Version(s): <br>\n4.2.0 (source: SKILL.md frontmatter and ClawHub release metadata) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v4.2.0:LICENSE\n\nMIT License\n\nCopyright (c) 2026 Chenmo\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\nArchive v4.1.0: 6 files, 9184 bytes\n\nFiles: LICENSE (1063b), README.md (4220b), scripts/publish-clawhub.sh (1159b), skill-card.md (1850b), SKILL.md (8998b), _meta.json (132b)\n\nFile v4.1.0:SKILL.md\n\n---\nname: windows-shell\nversion: 4.1.0\ndescription: \"Windows 命令行编码与兼容性规范。覆盖 GBK/UTF-8 编码、PowerShell/pwsh 互操作、Python/Node.js、Git 配置、代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。\"\nmetadata:\n  openclaw:\n    emoji: \"🪟\"\n    os: [windows]\n    homepage: \"https://github.com/Chenmo0414/win-encoding-fix\"\n---\n\n# Windows 命令行编码规范\n\n用户系统：Windows 10/11（代码页 GBK/936），终端：MSYS2/Git Bash。以下规则均在真实 GBK 环境逐条实测验证。\n\n## 为什么会乱码（一句话原理）\n\n终端按 **UTF-8** 解码字节流，但 Windows 原生程序（PowerShell 5.1、CMD 工具、默认 Python）按 **GBK/936** 输出中文。字节被错误解码 → 乱码（如 `涓枃`、`M-DM-c`）。修复 = 让源头输出 UTF-8。\n\n## 快速参考\n\n| 场景 | 做法 |\n|------|------|\n| 执行 PowerShell 命令 | `powershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; ...'` |\n| PowerShell 中有 `$_`/`$null` | 外层用**单引号**，防止 bash 展开 |\n| PowerShell 读文件 | 加 `-Encoding UTF8`（pwsh 7 默认即 UTF-8，可省） |\n| 执行系统查询 | 用 `Get-CimInstance` 替代 `wmic` |\n| 执行 Python 单行命令 | 加 `-X utf8`：`python -X utf8 -c \"...\"`（**不要假设** `PYTHONUTF8` 已生效） |\n| 生成 Python 代码 | `open()` 必须带 `encoding='utf-8'` |\n| Node.js 调系统命令 | execSync 中用 PowerShell 包装 |\n| Git 中文文件名乱码 | 确认 `core.quotepath=false` |\n| 传统 CMD 工具 | **禁止直接使用**，全部走 PowerShell |\n\n## 环境自检（开工前可选执行）\n\n判断当前 shell 的编码是否已正确配置：\n\n```bash\npython -c \"import sys; print('utf8_mode=', sys.flags.utf8_mode)\"   # 期望 1；为 0 说明 Python 默认 GBK\necho \"PYTHONUTF8=$PYTHONUTF8\"                                       # 期望 1；为空说明环境变量未加载\n```\n\n**关键认知**：`PYTHONUTF8` 等变量若只写在 `~/.bash_profile`，**非登录 / 非交互 shell 不会加载它**（AI 助手与脚本通常正是这种 shell）。因此：\n\n- 持久生效请配置 **Windows 用户级环境变量**（被所有进程继承，重启终端后生效）；\n- 当前会话内最可靠的做法是**每条命令显式带编码参数**（见下方各规则）。\n\n## 环境前置条件（持久配置，建议一次性执行）\n\n```bash\n# 1) Windows 用户级环境变量 —— 最可靠，所有进程继承（重启终端后生效）\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8;\n  [Environment]::SetEnvironmentVariable(\"PYTHONUTF8\", \"1\", \"User\");\n  [Environment]::SetEnvironmentVariable(\"PYTHONIOENCODING\", \"utf-8\", \"User\")'\n\n# 2) bash 显示相关变量（登录 shell 用），并让 .bashrc 也加载，覆盖非登录交互 shell\ncat >> ~/.bash_profile <<'EOF'\nexport PYTHONUTF8=1\nexport PYTHONIOENCODING=utf-8\nexport LANG=en_US.UTF-8\nexport LESSCHARSET=utf-8\nEOF\ngrep -q 'bash_profile' ~/.bashrc 2>/dev/null || echo '[ -f ~/.bash_profile ] && . ~/.bash_profile' >> ~/.bashrc\n\n# 3) Git 全局配置\ngit config --global core.quotepath false        # 中文文件名正常显示\ngit config --global core.autocrlf input         # 提交 LF，检出保持原样\ngit config --global i18n.commitEncoding utf-8    # commit 消息 UTF-8\ngit config --global i18n.logOutputEncoding utf-8\ngit config --global core.pager \"less -R\"\n```\n\n> 一键配置：`npx win-encoding-fix install --setup-env`\n\n## Shell 命令规则\n\n### 规则 1：PowerShell 命令必须加 UTF-8 前缀 + 外层单引号\n\n```bash\n# 标准模板（外层单引号 + UTF-8 前缀）\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; 你的命令'\n```\n\n**两个要点必须同时满足：**\n- `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8` — 不加则中文输出乱码\n- 外层**单引号** — 防止 bash 把 `$_`、`$null` 当作 bash 变量展开\n\n仅当命令中不含 `$` 变量时才可用外层双引号。\n\n**关于 pwsh（PowerShell 7）**：若系统装有 `pwsh`（`which pwsh` 可检测），它读写文件默认即 UTF-8，但**输出到管道仍可能因控制台代码页而乱码**（实测不稳定）。因此 pwsh 同样建议带上述前缀——前缀对 pwsh 无害、对 5.1 必需，统一加最省心。\n\n### 规则 2：PowerShell 读文件必须指定 UTF-8\n\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Content \"path\\file.txt\" -Encoding UTF8'\n```\n\nPowerShell 5.1 不加 `-Encoding UTF8` 会用 GBK 读取 UTF-8 文件（实测 `中文` → `涓枃`）。写文件同理用 `Set-Content -Encoding UTF8`。pwsh 7 默认 UTF-8 可省此参数，但加上无害。\n\n### 规则 3：禁止直接使用传统 CMD 工具和 cmd /c\n\n传统 CMD 工具输出 GBK 或 UTF-16，在 UTF-8 终端中全部乱码。`cmd /c` 同样不可用——`chcp 65001` 无法修复子进程编码（实测 `cmd /c \"chcp 65001 & echo 你好\"` 仍乱码）。\n\n**必须使用 PowerShell 替代：**\n\n| 禁止 | 替代 |\n|------|------|\n| `wmic` | `Get-CimInstance` |\n| `systeminfo` | `Get-ComputerInfo` 或 PS 包装 `systeminfo` |\n| `ipconfig` | `Get-NetIPAddress` / `Get-NetIPConfiguration` |\n| `netstat` | `Get-NetTCPConnection` |\n| `tasklist` | `Get-Process` |\n| `sc query` | `Get-Service` |\n| `reg query` | `Get-ItemProperty 'HKLM:\\...'` |\n| `net user` | `Get-LocalUser` |\n| `schtasks` | `Get-ScheduledTask` |\n| `findstr` | `Select-String` |\n| `cmd /c` | **永远不用** |\n\n在 PowerShell 中包装传统命令也可正确转码：\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; systeminfo | Select-Object -First 5'\n```\n\n### 规则 4：Python 命令行执行 —— 优先 `-X utf8`，不要假设环境\n\n实测：AI 助手与脚本运行在**非交互 shell**，`~/.bash_profile` 中的 `PYTHONUTF8` 不会被加载，`sys.flags.utf8_mode` 仍为 0，`python -c \"print('你好')\"` 直接乱码。\n\n**最可靠做法 —— 单行命令显式带 `-X utf8`：**\n```bash\npython -X utf8 -c \"print('你好世界')\"\n# 或临时设环境变量\nPYTHONUTF8=1 python script.py\n```\n\n`-X utf8` 同时让 `print()` 输出与 `open()` 默认读写都走 UTF-8，幂等无副作用，已是 UTF-8 环境时加它也不会出错。**生成代码时**仍应显式写 `encoding='utf-8'`（见规则 6），不依赖运行时标志。\n\n### 规则 5：Node.js 子进程调用系统命令\n\nNode.js 自身输出 UTF-8 没问题，但 `execSync`/`exec`/`spawn` 调用传统 CMD 工具时，输出是 GBK，`toString('utf-8')` 会乱码。\n\n**修复**：让子进程通过 PowerShell 输出 UTF-8：\n```javascript\nexecSync('powershell -Command \"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; systeminfo\"').toString('utf-8')\n```\n\n## 代码生成规则\n\nAI 生成代码时必须遵循以下规则，确保产出的代码在 Windows 上编码正确。\n\n### 规则 6：Python 文件 I/O 必须指定编码\n\n```python\n# 正确 — 显式指定 encoding\nwith open('data.txt', 'r', encoding='utf-8') as f:\n    content = f.read()\n\nwith open('output.txt', 'w', encoding='utf-8') as f:\n    f.write(content)\n\n# 错误 — 裸 open() 在 Windows 上默认 GBK（实测 locale.getpreferredencoding() = cp936）\nwith open('data.txt', 'r') as f:  # 不要这样写\n    content = f.read()\n```\n\n同样适用于 `json.load`/`json.dump`、`csv.reader`、`pathlib.Path.read_text()` 等需要文件对象的场景。\n\nPython subprocess 调用系统命令时也需注意编码：\n```python\nimport subprocess\nresult = subprocess.run(\n    ['powershell', '-Command', '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Process'],\n    capture_output=True, text=True, encoding='utf-8'\n)\n```\n\n### 规则 7：Node.js 文件操作和子进程编码\n\n```javascript\n// 文件读写 — 显式指定 utf-8\nfs.readFileSync('data.txt', 'utf-8')\nfs.writeFileSync('output.txt', content, 'utf-8')\n\n// 子进程调用 Windows 原生命令 — 通过 PowerShell 包装\nconst { execSync } = require('child_process')\nconst output = execSync(\n  'powershell -Command \"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Service\"'\n).toString('utf-8')\n```\n\n### 规则 8：Git 中文支持\n\n环境已配置 `core.quotepath=false`，中文文件名在 `git status`/`git diff` 中正常显示。\n\n如果发现中文文件名仍显示为 `\\346\\265\\213\\350\\257\\225` 形式，执行：\n```bash\ngit config --global core.quotepath false\n```\n\n## 格式化技巧\n\n- 宽表格加 `| Out-String -Width 200` 防截断\n- `Format-Table -AutoSize` 自适应列宽\n- `Format-List` 展示详细单条记录\n- `Select-Object` 控制返回字段数量\n\n## 不需要包装的工具\n\n以下工具本身输出 UTF-8，可直接使用：\n- `git`、`node`、`npm`、`pnpm`、`bun`、`cargo`、`go`\n- bash 内置：`echo`、`cat`、`ls`、`grep` 等\n- `python`：加 `-X utf8` 后可直接使用（见规则 4）\n\nFile v4.1.0:README.md\n\n# win-encoding-fix\n\nWindows Shell encoding skill for AI coding assistants. Fixes GBK/UTF-8 encoding issues on Windows 10+ with MSYS2/Git Bash.\n\nTested and verified on real Windows 10 (code page 936/GBK) environments.\n\n## Problem\n\nOn Windows with GBK locale, AI coding assistants (Claude Code, Codex, OpenClaw) frequently produce garbled Chinese output because:\n\n- PowerShell outputs GBK by default, but the terminal expects UTF-8\n- Traditional CMD tools (`wmic`, `systeminfo`, etc.) output UTF-16 or GBK\n- Python `print()` and `open()` default to GBK\n- Node.js `execSync` decodes GBK output as UTF-8\n- Git shows Chinese filenames as octal escapes\n\nThis skill teaches AI assistants to handle all these cases correctly.\n\n> **A subtle trap this skill solves:** exports written to `~/.bash_profile` are only sourced by *login* shells. AI assistants and scripts run in **non-interactive** shells that source neither `.bash_profile` nor `.bashrc`, so `PYTHONUTF8=1` set there never reaches the Python the agent actually runs (`sys.flags.utf8_mode` stays `0`). v4.1.0 fixes this by setting **Windows User-level environment variables** (inherited by every process) and by having `.bashrc` source `.bash_profile`.\n\n## What's Included\n\n- **8 encoding rules** covering PowerShell/pwsh, CMD, Python, Node.js, and Git\n- **Quick reference table** + an environment self-check\n- **Code generation rules** ensuring AI-written code handles encoding properly\n- **Robust environment setup** — Windows User env vars + bash rc files + git config\n\n## Install\n\n### npx (recommended)\n\n```bash\nnpx win-encoding-fix install --setup-env\n```\n\n### npm global\n\n```bash\nnpm install -g win-encoding-fix\nwin-encoding-fix install --setup-env\n```\n\n### Manual\n\nCopy `SKILL.md` to:\n\n| Platform | Path |\n|----------|------|\n| Claude Code | `~/.claude/skills/windows-shell/SKILL.md` |\n| Codex | `~/.codex/skills/windows-shell/SKILL.md` |\n| OpenClaw | `~/.openclaw/workspace/skills/windows-shell/SKILL.md` |\n\n## Commands\n\n```bash\nwin-encoding-fix install              # Install to auto-detected platforms\nwin-encoding-fix install --setup-env  # Also configure bash_profile + git\nwin-encoding-fix setup-env            # Only configure environment\nwin-encoding-fix uninstall            # Remove skill files\n\n# Custom install paths (if not using default locations)\nwin-encoding-fix install --claude=D:\\my-claude\nwin-encoding-fix install --codex=E:\\my-codex\nwin-encoding-fix install --openclaw=E:\\.openclaw\n```\n\n## Environment Setup\n\nThe `--setup-env` flag configures three layers so the fixes apply everywhere:\n\n**1. Windows User environment variables** (inherited by every process — the robust layer; takes effect after restarting the terminal):\n```\nPYTHONUTF8=1\nPYTHONIOENCODING=utf-8\n```\n\n**2. bash rc files** (for interactive Git Bash):\n```bash\n# ~/.bash_profile\nexport PYTHONUTF8=1\nexport PYTHONIOENCODING=utf-8\nexport LANG=en_US.UTF-8\nexport LESSCHARSET=utf-8\n# ~/.bashrc — so non-login shells get the same vars\n[ -f ~/.bash_profile ] && . ~/.bash_profile\n```\n\n**3. Git global config:**\n```bash\ngit config --global core.quotepath false        # Chinese filenames\ngit config --global core.autocrlf input         # LF on commit\ngit config --global i18n.commitEncoding utf-8\ngit config --global i18n.logOutputEncoding utf-8\ngit config --global core.pager \"less -R\"\n```\n\n## Rules Summary\n\n| # | Rule | Scope |\n|---|------|-------|\n| 1 | PowerShell/pwsh: UTF-8 prefix + single quotes | Shell |\n| 2 | PowerShell: `-Encoding UTF8` for file reads | Shell |\n| 3 | Never use legacy CMD tools or `cmd /c` | Shell |\n| 4 | Python: prefer `python -X utf8` (don't assume env is loaded) | Shell |\n| 5 | Node.js: PowerShell wrapper for `execSync` | Shell |\n| 6 | Python codegen: `open()` must have `encoding='utf-8'` | Code |\n| 7 | Node.js codegen: explicit `'utf-8'` in fs/child_process | Code |\n| 8 | Git: `core.quotepath=false` for Chinese filenames | Git |\n\n## Testing\n\n```bash\nnpm test    # runs node test/cli.test.js\n```\n\nThe suite covers install (custom paths, idempotency, content integrity), uninstall,\nhelp, unknown-command fallback, `setup-env` (rc files + git config, isolated from the\nreal environment), and SKILL.md frontmatter validity.\n\n## License\n\nMIT\n\nFile v4.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn78ryxatfm99gvwnvgexh8hkx847bk7\",\n  \"slug\": \"windows-shell\",\n  \"version\": \"4.1.0\",\n  \"publishedAt\": 1780553890753\n}\n\nFile v4.1.0:skill-card.md\n\n## Description: <br>\nWindows Shell helps AI coding assistants handle GBK/UTF-8 encoding, PowerShell/pwsh interoperability, Python, Node.js, Git configuration, and code generation on Windows 10/11 with MSYS2/Git Bash. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[chenmo0414](https://clawhub.ai/user/chenmo0414) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and coding agents use this skill to produce Windows shell commands and generated code that avoid GBK/UTF-8 mojibake across PowerShell, Python, Node.js, and Git workflows. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Optional setup can persistently change user-level environment variables, shell startup files, and global Git configuration. <br>\nMitigation: Review the exact setup commands before running them and record previous values so the changes can be undone if needed. <br>\n\n\n## Reference(s): <br>\n- [Project homepage](https://github.com/Chenmo0414/win-encoding-fix) <br>\n- [ClawHub skill page](https://clawhub.ai/chenmo0414/windows-shell) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown guidance with command and code snippets] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Windows-focused guidance for encoding-safe shell and code-generation behavior.] <br>\n\n## Skill Version(s): <br>\n4.1.0 (source: frontmatter and server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v4.1.0:LICENSE\n\nMIT License\n\nCopyright (c) 2026 Chenmo\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","readmeExcerpt":"Skill: windows-shell Owner: chenmo0414 Summary: Windows 命令行工作规范：先选对 shell（默认 Git Bash），再避开编码与 MSYS2 参数改写两类陷阱。覆盖 GBK/UTF-8、BOM、MSYS2 路径转换、PowerShell/pwsh、WSL 判定、Python/Node.js、Git 配置与代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。细节按需读 references/。 Tags: latest:5.3.0 Version history: v5.3.0 | 2026-08-20T10:52:34.177Z | user 补两条，否掉一条。候选来自 agent 实测自报的「规范没写、只能靠自有知识现推」， 再用 TokenHub 多模型探针筛出其中模型真不会的（每格 5 次采样，共 240 次调","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"node app.js /api/v1/users          # 程序实收 D:/Program Files/Git/api/v1/users\ndocker run -v /app:/app ...        # -v 后面被吃掉\nreg query \"HKCU\\Environment\"       # 错误: 无效语法。"},{"language":"bash","snippet":"MSYS_NO_PATHCONV=1 node app.js /api/v1/users    # 单条前置，不要全局导出"},{"language":"bash","snippet":"powershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; 你的命令'"},{"language":"bash","snippet":"od -c legacy.txt | head -2        # 或 xxd；Git Bash 没有 hexdump"},{"language":"text","snippet":"同一段 $s = \"腾讯\"，只差 BOM：\n  PS 5.1 无 BOM  →  $s.Length = 3   ✗   字符串在内存里是 3 个错字符\n  PS 5.1 有 BOM  →  $s.Length = 2   ✓"},{"language":"bash","snippet":"powershell -NoProfile -Command '$s=\"中文测试\"; Write-Output $s.Length'   # → 4，正确"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: windows-shell\nversion: 5.3.0\ndescription: \"Windows 命令行工作规范：先选对 shell（默认 Git Bash），再避开编码与 MSYS2 参数改写两类陷阱。覆盖 GBK/UTF-8、BOM、MSYS2 路径转换、PowerShell/pwsh、WSL 判定、Python/Node.js、Git 配置与代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。细节按需读 references/。\"\nlicense: MIT\nmetadata:\n  openclaw:\n    emoji: \"🪟\"\n    os: [windows]\n    homepage: \"https://github.com/Chenmo0414/win-encoding-fix\"\n---\n\n# Windows 命令行工作规范\n\n用户系统：Windows 10/11（代码页 GBK/936），终端：MSYS2/Git Bash。\n\n**本文件是速查与路由表。** 每条规则下面标了「细读」，只在真正遇到那类问题时再去读对应的\n`references/` 文件——不要一次性全部读完。\n\n## 一、先分清是哪一类问题\n\n在 Git Bash 里执行命令出问题，绝大多数是这两类之一。**先判类，再套解法**，两类的解法完全不通用：\n\n| 症状 | 类别 | 第一反应 |\n|------|------|------|\n| 输出乱码（`涓枃`、`M-DM-c`、方块字） | **编码** | 让源头输出 UTF-8 |\n| 没报错但**结果就是不对**（参数变了值、行数少一行） | **静默失败** | 见第 1、3 条，必须交叉验证 |\n| 报「无效语法 / invalid / 找不到文件」，或参数悄悄变了值 | **MSYS2 参数改写** | `MSYS_NO_PATHCONV=1` |\n\n拿编码的解法去治参数改写，怎么加前缀都不好使——这是最常见的误诊。\n\n## 二、选对 shell（默认 Git Bash）\n\n| 你要做的事 | 用哪个 |\n|------|------|\n| npm / node / npx / tsc / vitest / python / pip / pytest / git / ssh | **Git Bash** |\n| Windows 服务、注册表、事件日志、计划任务、证书、.NET/COM、对象管道 | **PowerShell**（单条命令切过去，主线不搬家） |\n| 跑 Makefile、需要 gcc/rsync，或重 I/O 构建且项目能整个搬进 ext4 | **WSL** |\n| 需要管理员权限 | **交给人做**——UAC 弹窗 agent 点不了，命令会一直挂着 |\n\n项目文件在 `C:\\`/`D:\\` 上时，**不要用 WSL 去操作它**：跨 `/mnt/*` 比纯 Windows 还慢 4–6 倍，\n且惩罚随项目规模线性放大。\n\n> 细读：判断依据与完整决策表 → [shell-routing.md](references/shell-routing.md)；\n> WSL 值不值得上 → [wsl.md](references/wsl.md)\n\n## 三、必须知道的六条\n\n下面六条是实测中真正拉开差距的。其余规则都在 `references/`。\n\n### 1. 以 `/` 开头的参数会被静默改写\n\nGit Bash 把它当 Unix 路径转成 Windows 路径再传给原生程序。**不报错、退出码 0、参数已经变了**：\n\n```bash\nnode app.js /api/v1/users          # 程序实收 D:/Program Files/Git/api/v1/users\ndocker run -v /app:/app ...        # -v 后面被吃掉\nreg query \"HKCU\\Environment\"       # 错误: 无效语法。\n```\n\n```bash\nMSYS_NO_PATHCONV=1 node app.js /api/v1/users    # 单条前置，不要全局导出\n```\n\n全局导出会让 `/c/Users/...` 这类本该转换的参数也不转。\n\n> 细读：另两种绕法、符号链接退化 → [msys2.md](references/msys2.md)\n\n### 2. PowerShell 5.1 输出中文必须加前缀\n\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; 你的命令'\n```\n\n外层用**单引号**（防 bash 展开 `$_`、`$null`）。pwsh 7 不需要这个前缀，加了也无害。\n外部程序（node/python）自己写的 UTF-8 穿过 PowerShell 不会被改。\n\n### 3. 读遗留文件前先验编码，别硬套 UTF-8\n\n对一个真正的 GBK/936 文件强加 `-Encoding UTF8` 会读出乱码。先看字节再决定：\n\n```bash\nod -c legacy.txt | head -2        # 或 xxd；Git Bash 没有 hexdump\n```\n\n| 文件真实编码 | PS 5.1 | pwsh 7 |\n|------|------|------|\n| UTF-8 | `-Encoding UTF8`（**必须显式写**） | 默认即可 |\n| GBK/936 | `-Encoding Default` | `[System.Text.Encoding]::GetEncoding(936)` |\n\n**PS 5.1 读无 BOM 的 UTF-8 不加 `-Encoding UTF8` 会静默出错**——不是乱码那么显眼，\n而是行数直接算错、退出码仍为 0。实测：一个 3 行的 UTF-8 文件，某行末尾字节是\n`a1 8c 0a`，PS 按 GBK 把 `8c` 当双字节前导、吞掉紧随的换行，`Get-Content` 返回\n**2 行**且 `$?` 为 `True`。性质与上面第 1 条的参数改写相同：**结果错、不报错**。\n所以 **PS 5.1 读任何文本文件都显式指定 `-Encoding`**，别赌默认值。\n\n**含中文的 `.ps1` 脚本文件必须存成 UTF-8 with BOM**。PS 5.1 读脚本时没有 BOM 就按\nANSI/GBK 解析，中文字面量被拆错——而且多数情况**不报错**：\n\n```\n同一段 $s = \"腾讯\"，只差 BOM：\n  PS 5.1 无 BOM  →  $s.Length = 3   ✗   字符串在内存里是 3 个错字符\n  PS 5.1 有 BOM  →  $s.Length = 2   ✓\n```\n\n最阴险的是 `Write-Output $s` **打印"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn78ryxatfm99gvwnvgexh8hkx847bk7\",\n  \"slug\": \"windows-shell\",\n  \"version\": \"5.3.0\",\n  \"publishedAt\": 1787223154177\n}"},{"path":"references/encoding.md","content":"# 编码细节（GBK / UTF-8 / BOM）\n\n主文件 `SKILL.md` 只放了最常用的两条。遇到下列任一情况时读本文：\n读写文件出现乱码、需要处理 GBK 遗留文件、需要写无 BOM 的 UTF-8、\nPowerShell 重定向编码不对、管道方向的编码问题、传统 CMD 工具输出乱码。\n\n## 环境自检（开工前可选执行）\n\n判断当前 shell 的编码是否已正确配置：\n\n```bash\npython -c \"import sys; print('utf8_mode=', sys.flags.utf8_mode)\"   # 期望 1；为 0 说明 Python 默认 GBK\necho \"PYTHONUTF8=$PYTHONUTF8\"                                       # 期望 1；为空说明环境变量未加载\n```\n\n**关键认知**：`PYTHONUTF8` 等变量若只写在 `~/.bash_profile`，**非登录 / 非交互 shell 不会加载它**（AI 助手与脚本通常正是这种 shell）。因此：\n\n- 持久生效请配置 **Windows 用户级环境变量**（被所有进程继承，重启终端后生效）；\n- 当前会话内最可靠的做法是**每条命令显式带编码参数**（见下方各规则）。\n\n## 环境前置条件（持久配置，建议一次性执行）\n\n```bash\n# 1) Windows 用户级环境变量 —— 最可靠，所有进程继承（重启终端后生效）\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8;\n  [Environment]::SetEnvironmentVariable(\"PYTHONUTF8\", \"1\", \"User\");\n  [Environment]::SetEnvironmentVariable(\"PYTHONIOENCODING\", \"utf-8\", \"User\")'\n\n# 2) bash 显示相关变量（登录 shell 用），并让 .bashrc 也加载，覆盖非登录交互 shell\ncat >> ~/.bash_profile <<'EOF'\nexport PYTHONUTF8=1\nexport PYTHONIOENCODING=utf-8\nexport LANG=en_US.UTF-8\nexport LESSCHARSET=utf-8\nEOF\ngrep -q 'bash_profile' ~/.bashrc 2>/dev/null || echo '[ -f ~/.bash_profile ] && . ~/.bash_profile' >> ~/.bashrc\n\n# 3) Git 全局配置\ngit config --global core.quotepath false        # 中文文件名正常显示\ngit config --global core.autocrlf input         # 提交 LF，检出保持原样\ngit config --global i18n.commitEncoding utf-8    # commit 消息 UTF-8\ngit config --global i18n.logOutputEncoding utf-8\ngit config --global core.pager \"less -R\"\n```\n\n> 一键配置：在 [skill-factory](https://github.com/Chenmo0414/win-encoding-fix) 仓库里执行 `node bin/cli.js setup-env`\n\n### 规则 1：PowerShell 命令必须加 UTF-8 前缀 + 外层单引号\n\n```bash\n# 标准模板（外层单引号 + UTF-8 前缀）\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; 你的命令'\n```\n\n**两个要点必须同时满足：**\n- `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8` — 不加则中文输出乱码\n- 外层**单引号** — 防止 bash 把 `$_`、`$null` 当作 bash 变量展开\n\n仅当命令中不含 `$` 变量时才可用外层双引号。\n\n**前缀到底什么时候必需**（v4.3.0 实测，各采样 12 次，结果完全稳定）：\n\n| 中文的来源 | PS 5.1 无前缀 | PS 5.1 加前缀 | pwsh 7 无前缀 |\n|------|------|------|------|\n| PowerShell 自己产出（`Write-Output`、cmdlet 结果） | **GBK ×12 → 乱码** | UTF-8 ×12 ✅ | **UTF-8 ×12 ✅** |\n| 外部程序产出（`node -e`、`python` 等） | UTF-8 ×12 ✅ | UTF-8 ×12 ✅ | UTF-8 ×12 ✅ |\n\n- **PS 5.1 必须加前缀**：只要中文由 PowerShell 自己产出，不加就是稳定乱码，没有侥幸。\n- **pwsh 7 不需要前缀**：实测 12/12 稳定 UTF-8。加了无害，脚本要兼容 5.1 时统一加是合理的，但不必因为「怕 pwsh 不稳」而加。\n- **外部程序的输出不受影响**：`node`/`git`/`python` 自己写 UTF-8 到 stdout，穿过 PowerShell 不会被改。所以「PS 包装」只对遵守控制台代码页的 Windows 原生工具才有意义（见规则 3）。\n\n### 规则 2：PowerShell 读写文件 —— `-Encoding` 必须匹配文件真实编码\n\n**读 UTF-8 文件**：PowerShell 5.1 不加 `-Encoding UTF8` 会用 GBK 读取，实测 `中文` → `涓枃`。\n\n```bash\npowershell -Command '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Content \"path\\file.txt\" -Encoding UTF8'\n```\n\n**⚠️ 读 GBK 遗留文件（本机最常见）**：反过来，对一个真正的 GBK/936 文件强加 `-Encoding UTF8` 会**读出乱码**。`-Encoding` 的值必须等于文件的真实编码：\n\n| 文件真实编码 | PS 5.1 读法 | pwsh 7 读法 |\n|------|------|------|\n| UTF-8 | `-Encoding UTF8` | 默认即可（或 `-Encoding utf8`） |\n| GBK/936（遗留） | `-Encoding Defaul"},{"path":"references/gitbash-pitfalls.md","content":"# Git Bash 的五个坑\n\n在 Git Bash 下遇到非编码类异常时读本文：参数被改写、符号链接失效、\nvenv 激活路径异常、工具缺失、SSH 密钥不通用、管道吞退出码。\n\n## Git Bash 的五个坑\n\n选了 Git Bash，这五个必须知道，否则会以为是代码的问题。\n\n### 坑 1：以 `/` 开头的参数会被改写（静默）\n\nMSYS2 把它们当 Unix 路径转成 Windows 路径再传给程序。**不报错、退出码正常、参数已经变了**：\n\n```bash\nnode app.js /api/v1/users     # 程序收到 D:/Program Files/Git/api/v1/users\nprog /S /C                    # → S:/ C:/\ndocker run -v /app:/app ...   # -v 后面被吃掉\n```\n\n```bash\n# 解法：单条命令前置，别全局导出\nMSYS_NO_PATHCONV=1 node app.js /api/v1/users\n```\n\n全局导出会让 `/c/Users/...` 这类你确实希望被转换的参数也不转了。\n\n### 坑 2：`ln -s` 默认产出的是副本\n\n```bash\nln -s t.txt l.txt && ls -l l.txt      # -rw-r--r--  ← 是副本，不是链接\nexport MSYS=winsymlinks:nativestrict  # 修复后 → lrwxrwxrwx\n```\n\n**pnpm workspace、npm link、monorepo 本地依赖都依赖真符号链接**，退化成副本会表现为「改了源码不生效」。需先启用 Windows 开发者模式。\n\n### 坑 3：venv 的 `activate` 会拼出畸形路径\n\n```bash\nsource .venv/Scripts/activate    # VIRTUAL_ENV 丢盘符，路径变成 /d/proj/\\proj\\.venv/Scripts/python\n```\n\n虽然仍能解析，但不可靠。**直接调解释器，绕开 activate**：\n\n```bash\n./.venv/Scripts/python.exe -m pytest\n./.venv/Scripts/python.exe -m pip install -r requirements.txt\n```\n\n### 坑 4：工具集不全\n\n`jq`、`make`、`gcc`、`rsync` 都**没有**。跑 Makefile 的项目直接卡住——那种情况上 WSL，不要试图在 Git Bash 里凑。\n\n### 坑 5：SSH 密钥位置与 WSL 不通用\n\nGit Bash 与 Windows 共用 `C:\\Users\\你\\.ssh`，**WSL 用的是独立的 `/root/.ssh`**。在 Windows 配好的 SSH，到 WSL 里等于从零开始。\n\n而且 `/mnt/*` 上的文件在 WSL 眼里权限是 `777`，OpenSSH 会判定 `bad permissions` 直接忽略该密钥。要在 WSL 里用 ssh，密钥必须复制到 ext4 并 `chmod 600`。Git Bash 没有这个问题（它走 Windows ACL，不看 POSIX 权限位）。\n\n### 附：管道会吞掉退出码\n\n这不是 Git Bash 特有，但 agent 最容易在这里误判成功：\n\n```bash\nnpm install ... | tail -25      # $? 是 tail 的，不是 npm 的\nset -o pipefail                 # 或用 ${PIPESTATUS[0]}\n```"},{"path":"references/msys2.md","content":"# MSYS2 参数改写与符号链接\n\n主文件已给出 `MSYS_NO_PATHCONV=1` 这一条速查。需要完整解释、\n其它两种绕法、或遇到符号链接/工具缺失问题时读本文。\n\n### 规则 6：MSYS2 会改写以 `/` 开头的参数\n\nGit Bash（MSYS2）在把参数交给 **非 MSYS2 程序**（即所有 Windows 原生 .exe）之前，会把看起来像 Unix 路径的参数自动转换成 Windows 路径。这是 MSYS2 的设计，不是 bug——但它**静默生效**，不报错、退出码正常，参数已经变了。\n\n```bash\nnode app.js /api/v1/users\n# 程序实际收到：D:/Program Files/Git/api/v1/users   ← 前面被拼上了 Git 安装目录\n\nprog /S /C                  # → 变成  S:/ C:/\ndocker run -v /app:/app ... # → -v 后面的参数被破坏\nreg query \"HKCU\\Environment\"   # → 错误: 无效语法。\nfindstr 中文 /tmp/x.txt        # → FINDSTR: 无法打开 C:x.txt\n```\n\n**什么时候会中招**：参数以 `/` 开头，且接收方是 Windows 原生程序。典型场景——REST 路径、Docker 卷映射、Windows 风格开关（`/S` `/C` `/query`）、注册表路径、传给 `.exe` 的 Unix 路径。\n\n**三种解法**（均实测有效）：\n\n```bash\n# A. 单条命令临时关闭（推荐，作用域最小）\nMSYS_NO_PATHCONV=1 reg query \"HKCU\\Environment\" /v PYTHONUTF8\nMSYS_NO_PATHCONV=1 node app.js /api/v1/users\n\n# B. 按参数排除\nMSYS2_ARG_CONV_EXCL='*' node app.js /api/v1/users\n\n# C. 双斜杠转义（只想保护单个参数时）\nnode app.js //api/v1/users\n```\n\n**不要全局导出 `MSYS_NO_PATHCONV=1`**：关掉转换后，`/c/Users/...` 这类你确实希望被转成 `C:\\Users\\...` 的参数也不再转换，会引入另一批问题。按需在单条命令前加。\n\n> 与编码问题的区别：编码问题表现为**乱码**，参数改写表现为**语法错/找不到文件/行为不对但不报错**。诊断时先看报错形态，别拿编码的解法去治路径的病。\n\n### 规则 7：Git Bash 的 `ln -s` 默认产出的是副本\n\n```bash\nln -s t.txt l.txt && ls -l l.txt\n# 默认：  -rw-r--r--  ← 普通文件副本，不是链接\n```\n\n对普通脚本无所谓，但 **pnpm workspace、npm link、monorepo 的本地依赖都依赖真符号链接**，退化成副本会导致改了源码却不生效、或磁盘占用异常。\n\n```bash\n# 修复：产出真正的符号链接（lrwxrwxrwx）\nexport MSYS=winsymlinks:nativestrict\nln -s t.txt l.txt && ls -l l.txt      # → lrwxrwxrwx ... l.txt -> t.txt\n```\n\nWindows 10/11 需先启用**开发者模式**（设置 → 隐私和安全性 → 开发者选项），否则创建符号链接要管理员权限。检查是否已启用：\n\n```bash\npowershell -NoProfile -Command '(Get-ItemProperty \"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock\").AllowDevelopmentWithoutDevLicense'\n# 返回 1 = 已启用\n```\n\n## 不需要包装的工具\n\n以下工具本身输出 UTF-8，可直接使用：\n- `git`、`node`、`npm`、`pnpm`、`bun`、`cargo`、`go`\n- bash 内置：`echo`、`cat`、`ls`、`grep` 等\n- `python`：加 `-X utf8` 后可直接使用（见规则 4）\n\n> **编码没问题 ≠ 完全没坑**：这些工具的**输出编码**是干净的，但只要给它们传以 `/` 开头的参数，\n> 仍会被 MSYS2 改写（见规则 6）；`pnpm` 的 workspace 还依赖真符号链接（见规则 7）。\n> 两件事互相独立，别因为「这个工具在白名单里」就放松警惕。"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Windows 命令行工作规范：先选对 shell（默认 Git Bash），再避开编码与 MSYS2 参数改写两类陷阱。覆盖 GBK/UTF-8、BOM、MSYS2 路径转换、PowerShell/pwsh、WSL 判定、Python/Node.js、Git 配置与代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。细节按需读 references/。 Skill: windows-shell Owner: chenmo0414 Summary: Windows 命令行工作规范：先选对 shell（默认 Git Bash），再避开编码与 MSYS2 参数改写两类陷阱。覆盖 GBK/UTF-8、BOM、MSYS2 路径转换、PowerShell/pwsh、WSL 判定、Python/Node.js、Git 配置与代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。细节按需读 references/。 Tags: latest:5.3.0 Version history: v5.3.0 | 2026-08-20T10:52:34.177Z | user 补两条，否掉一条。候选来自 agent 实测自报的「规范没写、只能靠自有知识现推」， 再用 TokenHub 多模型探针筛出其中模型真不会的（每格 5 次采样，共 240 次调","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1075,"uniquenessScore":45,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T11:29:54.514Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T11:29:54.514Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T14:13:02.144Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}