Problem entry · machine-readable · 编码代理与终端

PowerShell 里调 wsl 输出乱码(每字符带空字节 / 每字符一行 / 中文变 �)

本页嵌入 #trove-entity JSON(本条目全量结构化数据);全库数据见 /agent/trove.json。

元数据

idwsl-pipe-encoding收录2026-08-29
问题域编码代理与终端主题分组容器与 WSL
适用工具wsl · 外部工具

症状

PowerShell(5.1 和 7)里调用 `wsl.exe ...` 时输出乱码:

```

w s l : �hKm0R ... # 每个字符中间有空格(UTF-16LE 的 00 字节被当字符显示)

wsl --help | more # 每字符一行([microsoft/WSL#13093](https://github.com/microsoft/WSL/issues/13093) 官方 issue)

中文内容变成 � 一类替换符

```

特征:**直接** `wsl echo hi > 文件`(cmd 重定向)字节正常(UTF-8);

坏的是**管道/捕获**场景:PowerShell 脚本赋值、CI 抓取、`|` 管道;

WSL 启动时还会混入一段代理检测横幅(stderr),加剧观感。

原因

wsl.exe 在管道/非 TTY 场景输出 **UTF-16LE(无 BOM)**,PowerShell 捕获后按自己的 stdout 编码

(实测 PS 5.1 与 pwsh 7 的 -Command 链路都是 UTF-16LE 无 BOM)写到下游;

下游按 UTF-8/单字节解码 → 每个 ASCII 字符被 00 隔开,中文全变 �。

这是 wsl.exe 的已知行为,2025 年的 #13093(WSL 2.5.7)仍存在。

解法

1. **脚本里设 `$env:WSL_UTF8 = "1"`** 再调 wsl(微软官方开关,实测 pwsh -File 下 wsl 输出变 UTF-8 正常);

不想改全局就放在脚本开头,或临时 `cmd /c "set WSL_UTF8=1 && wsl ..."`。

2. **复杂/长命令别硬拼命令行**(转义、长度都会炸):把脚本写到 WSL 内文件再执行:

`wsl bash /tmp/x.sh`;PowerShell 写文件走 UNC:`Set-Content \\wsl.localhost\Ubuntu\tmp\x.sh`。

3. **超长/特殊字符用 base64 传输**:`wsl bash -lc "echo <base64> | base64 -d | bash"`(实测通过,绕开引号/转义/长度三坑)。

4. **输出走文件**:让 wsl 内命令把结果写 `/tmp/out.txt`,再用 `Get-Content \\wsl.localhost\Ubuntu\tmp\out.txt` 读——

UTF-8 文件直读无编码问题,比管道可靠。

5. 辅助手段:`[Console]::OutputEncoding = [Text.Encoding]::UTF8` 影响 PowerShell 写控制台编码,可配合 1 使用。

6. WSL 启动横幅("检测到 localhost 代理配置...")是 stderr 噪声:设了 WSL_UTF8 后不乱码,仍介意可忽略或加 `2>$null`。

验证证据

- 本地实测(2026-08-29,Windows 11 + WSL Ubuntu,PowerShell 5.1 与 pwsh 7):

- 对照:cmd 直调 `wsl.exe echo hi > 文件` → 字节 `68 69 0A`(UTF-8,正常);

- 复现:`pwsh -NoProfile -Command "wsl echo hi" > 文件` → 字节 `77 00 73 00 6C 00 ...`(UTF-16LE 无 BOM),

下游按 UTF-8 显示即 "w s l :" 乱码——与本条目开头截图同款,#13093 同款;PowerShell 5.1 同样复现;

- 修复:ps1 里 `$env:WSL_UTF8="1"` 后 `& wsl.exe echo hi` → 字节 `77 73 6C 3A 20 E6 A3 80`(UTF-8 正常,中文不丢);

- base64 通道:`wsl bash -lc "echo dGVzdA== | base64 -d"` → test(exit 0);

- 文件中转:WSL 内写 /tmp/out.txt 后 UNC 读取,无编码问题(实践天天在用)。

- 实测复现日志(2026-08-29)

来源与证据

素材来源:https://github.com/microsoft/WSL/issues/13093

验证证据:Evidence details kept locally (2026-08-29)