windows终端乱码问题

解决

文章借助了AI,有些啰嗦,现在懒得改,留着自己看吧。

1. 诊断:先确认环境状态(30 秒)

bash 复制代码
pwsh -NoProfile -Command '
$oem = (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage").OEMCP
$cp  = [Console]::OutputEncoding.CodePage
$verdict = if ($cp -eq 65001) { "环境正常,管道中文不会乱" } else { "GBK 环境,管道中文会乱 → 执行第二步" }
"系统代码页 OEMCP   = $oem"
"pwsh 管道输出编码  = $cp"
"判定: $verdict"
'

输出示例(需要修复的环境):

ini 复制代码
系统代码页 OEMCP   = 936
pwsh 管道输出编码  = 936
判定: GBK 环境,管道中文会乱 → 执行第二步

如果判定是 GBK,直接看下一步;如果是 65001,你的环境没有这类问题,可以直接跳到原理部分了解来龙去脉。

2. 修复:把系统代码页切到 UTF-8

bash 复制代码
# ① 备份(回滚靠它,建议先做)
reg export "HKLM\SYSTEM\CurrentControlSet\Control\Nls\CodePage" "$HOME\code-page-backup.reg" /y

# ② 切换:ACP=ANSI 代码页,OEMCP=控制台代码页,MACCP=Mac 代码页 → 全部 65001(UTF-8)
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Nls\CodePage" /v ACP   /t REG_SZ /d 65001 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Nls\CodePage" /v OEMCP /t REG_SZ /d 65001 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Nls\CodePage" /v MACCP /t REG_SZ /d 65001 /f

不想敲命令也可以:控制面板 → 区域 → 管理 → 更改系统区域设置 → 勾选 "Beta: 使用 Unicode UTF-8 提供全球语言支持"------本质是同一件事。

3. 验证与安全须知

bash 复制代码
pwsh -NoProfile -Command '[Console]::OutputEncoding.CodePage'   # → 65001
pwsh -NoProfile -Command "Write-Output '中文测试'"               # → 中文测试(不再乱码)

动手前先了解这几件事:

说明
改了什么 系统 3 个代码页注册表键:ACP / OEMCP / MACCP → 65001
怎么回滚 reg import "$HOME\code-page-backup.reg"(或删掉这几个键)
需要权限 管理员(reg add HKLM 要求提权)
可能的影响 极少数硬编码 GBK 的老软件可能显示乱码(现代开发工具不受影响)

这三个键分别管什么(都是历史遗留,各管一个"编码世界"):

管什么 谁受影响
ACP Win32 ANSI 字符串(非 Unicode 程序的窄字符串 API) 硬编码 GBK 的老 GUI 软件------这就是"老软件可能乱码"的风险源;现代工具走 Unicode API,不受影响
OEMCP 控制台/管道输出(新控制台默认代码页、无控制台进程的输出回退编码) cmd、pwsh 管道输出------本次乱码的根源就在它
MACCP 古 Macintosh 兼容 基本已废弃,勾选框会一起改,顺手为之

改完不用重启------新进程立即生效,原因在第二部分。


第二部分 · 原理与延伸

1. 乱码先看字节

乱码的本质是编码错位:发送端和接收端各说各话。与其猜,不如直接看发送端发的是什么字节

bash 复制代码
$ echo '中文测试' | od -A x -t x1z
e4 b8 ad e6 96 87 e6 b5 8b e8 af 95    # UTF-8(e4 b8 ad = "中")

$ pwsh -NoProfile -Command "Write-Output '中文测试'" | od -A x -t x1z
d6 d0 ce c4 b2 e2 ca d4                # GBK(d6 d0 = "中")

同为"中文测试"四个字,UTF-8 和 GBK 的字节完全不同。看到 d6 d0 开头,基本可以断定是 GBK 环境的数据,被按 UTF-8 解读了。

2. 乱码的四种类型

"乱码"是个统称,实际按字节在哪个环节错位,大致分四类:

类型 典型症状 字节证据 根因 修法
文件读写 脚本读旧文件中文乱 文件字节是 GBK(或 BOM 不匹配) 老文件是 GBK,现代工具默认按 UTF-8 读 新文件一律用 UTF-8;读旧 GBK 文件时显式 -Encoding GBK,后续转存为 UTF-8
管道传输 程序输出到终端/CI 乱 d6 d0 vs e4 b8 ad(本文主线) 输出用系统代码页 936,接收端按 UTF-8 系统代码页改 65001
终端显示 终端里直接显示乱 --- 终端 code page ≠ 输出字节 终端编码设成 UTF-8(chcp 65001 或终端设置)
参数传递 中文参数变问号/被吞 --- 旧版 $OutputEncoding 默认 ASCII 用 pwsh 7(默认 UTF-8)

方向只有一个:能 UTF-8 就 UTF-8。它是国际标准、现代工具链的默认值;GBK 是历史遗留,只该出现在"读旧文件"这一个场景里。

早期用 Windows PowerShell 5.1 写脚本,UTF-8 编码总是出问题------写出来要么带 BOM 要么被 ANSI 默认值坑,读写双方对不上,怎么调都别扭。最后干脆用 GBK 写脚本,眼不见心不烦。后面试用 Zed 编辑器,它只认 UTF-8,GBK 文件直接没法看------那一刻意识到,UTF-8 是大势所趋,逃避不是办法。于是认真找"UTF-8 下不乱码"的写法,最终落到 pwsh:文件默认 UTF-8、参数传递也默认 UTF-8,5.1 时代最磨人的两类乱码当场消失。

为什么 5.1 执行 UTF-8 脚本会乱?三个机制叠加:

  1. 解析不认"无 BOM 的 UTF-8" 。5.1 读 .ps1 文件时,文件头有 BOM 就按 BOM 的编码解码,没有 BOM 就按系统 ANSI 代码页(中文系统 = GBK)解码 。而现代编辑器默认存 UTF-8 无 BOM------文件里是正确的 UTF-8,5.1 却按 GBK 读,中文从解析那一刻就错位了。(对调验证:pwsh 7 无 BOM 按 UTF-8 读,把 GBK 文件喂给它同样乱------方向反了,机制逻辑一样。)
  2. 自己的输出默认值不统一 。5.1 里 > / Out-File 默认 UTF-16LE(带 BOM),Set-Content 默认 ANSI(GBK)。用 5.1 写"UTF-8 脚本",写出来的往往根本不是 UTF-8,换个工具打开又是一轮乱。
  3. $OutputEncoding 默认 ASCII。脚本里把中文传给 git、curl 等原生命令时,中文参数变成问号(微软官方差异文档确认:5.1 默认 ASCII → 7 改为 UTF-8 NoBOM)。

pwsh 7 修了这三条:无 BOM 按 UTF-8 读、文件默认 UTF-8 无 BOM、$OutputEncoding 默认 UTF-8。但它没修第四条------管道/控制台输出仍跟随系统代码页,这正是下一节"换了 pwsh 7 还乱"的原因。

这套分类的价值在于:先抓字节确认编码,再查"发送端用什么编码输出、接收端按什么编码解读",错位在哪一环,就修哪一环------不用背方案,每次都能自己推。

3. 为什么换了 pwsh 7 还会乱

"我从 powershell 5.1 换到 pwsh 7 了,怎么管道乱码还在?"------因为 pwsh 7 的 UTF-8 默认值只覆盖部分场景

输出对象 编码规则 pwsh 7 表现
文件 (Out-File / Set-Content / > 文件默认编码 UTF-8 无 BOM ✅
管道/控制台(stdout 被重定向) [Console]::OutputEncoding = 系统代码页 936,GBK ❌

powershell 5.1 和 pwsh 7 在"管道输出"上完全一样 ,都跟随系统代码页。换版本能治好文件乱码,但管道乱码和版本无关------它由系统代码页 决定。所以诊断脚本查的是 [Console]::OutputEncoding.CodePage,不是 PowerShell 的版本号。

相关推荐
0566461 小时前
python高级——Python 类型提示与 Pydantic
网络·人工智能·windows·python·学习
小桥流水---人工智能2 小时前
Windows下Conda无法创建Python 3.11虚拟环境:从镜像源404到PackagesNotFoundError的完整排查与解决
windows·conda·python3.11
sukalot2 小时前
windows 驱动实例分析系列: wireguard-nt驱动分析-api篇(二)
windows
MNLoser2 小时前
AI agent开发——LangGraph接入持久化
linux·人工智能·windows·python
小桥流水---人工智能3 小时前
Windows下RTX 5070安装PyTorch GPU完整教程:Python 3.11 + PyTorch 2.8.0 + CUDA 12.9
pytorch·windows·python3.11
爱学习的小白柏14 小时前
【AI问数技术】多Agent协同架构:查询规划/SQL生成/洞察分析/报告生成
java·网络·人工智能·windows·sql·架构·llama
何以解忧,唯有..18 小时前
Python 中获取目录操作完全指南
windows·python·microsoft
YCOSA202521 小时前
雨晨 Windows 10 轻装版 64位 六合一 VIP 19045.7663
windows·物联网
DOLA_Tech1 天前
电脑共享文件夹教程(Windows、统信UOS、银河麒麟)
windows·电脑