WSL 中文方块与乱码修复:Windows Terminal 字体、UTF-8 Locale 排查(2026)

维护说明(2026 年 9 月 1 日):本页现在先提供适用于当前 WSL 与 Windows Terminal 的分层排查方法。文末保存完整的 2019 年正文,仅规范化行尾空白;其中手工编辑 locale、安装旧 Linux 字体包和第三方参考链接只属于历史记录,不是现行依据。

“中文方块”和“乱码”看起来相近,根因却不同:

  • □□□ 或空心方框通常表示终端所选字体没有对应 glyph;
  • 中文 一类字符通常表示 UTF-8 字节被按错误编码解读;
  • 通常表示输入含有无法按当前解码方式解释的字节。

先确定问题发生在 Windows 终端渲染、WSL locale,还是某个文件/程序的编码。不要同时更换字体、locale 和应用配置,否则即使恢复也很难知道真正原因。

1. 记录 WSL、终端和发行版环境

在 PowerShell 中记录 WSL 状态:

wsl --version
wsl --status
wsl --list --verbose

旧的 inbox WSL 可能不支持 wsl --version;Microsoft 的排障文档建议这种情况下记录 wsl.exe --status。同时记录 Windows 版本、Windows Terminal 版本、所用 Terminal profile 和 Ubuntu 版本。不要为了排障先升级,先保存能够复现问题的版本信息。

在 Ubuntu/WSL 中运行:

printf '中文测试:你好,世界\n'
locale
locale charmap
locale -a | sed -n '1,40p'
python3 - <<'PY'
import locale
import sys

print("stdout:", sys.stdout.encoding)
print("preferred:", locale.getpreferredencoding(False))
print("sample:", "中文测试:你好,世界")
PY

若第一行已经是方块而 locale charmap 显示 UTF-8,优先检查 Windows Terminal 字体。若 Python 报编码错误或 charmap 不是 UTF-8,再处理 locale。若只有一个应用或文件异常,先跳到第 5 节。

2. 修复方块:检查 Windows Terminal profile 的字体

WSL shell 输出的是字符与控制序列,Windows Terminal 负责把终端格子绘制到屏幕。Microsoft 的文档说明字体设置属于各 profile 的 Appearance 配置;因此在 WSL 中安装字体不会自动改变 Windows Terminal 当前使用的字体。

在 Windows Terminal 中:

  1. Ctrl+, 打开 Settings;
  2. 选择实际使用的 Ubuntu/WSL profile;
  3. 打开 Appearance;
  4. 查看 Font face,并选择已安装、确认含有简体中文字形的字体;
  5. 新开一个 tab,再运行上一节的中文测试。

Microsoft 的字体目录把 Microsoft YaHei 列为简体中文字体,并说明它随 Windows 10 和 Windows 11 提供。可以先用 Windows 的 Settings > Personalization > Fonts 确认该字体在本机存在。若组织要求等宽字体,应从可信来源安装并验证一款覆盖 CJK 的等宽字体,再在 Terminal profile 中选择其准确 family name。

使用 JSON 配置时,下面只是应放在目标 profile 内的片段,不是完整 settings.json

"font": {
  "face": "Microsoft YaHei",
  "size": 12
}

Microsoft 文档说明 font 对象适用于 Windows Terminal 1.10 及以上;更早版本使用旧的 fontFace 属性。对于当年的 legacy Console Host,不建议继续复制注册表字体技巧;在受支持的 Windows 10 22H2 或 Windows 11 上优先使用当前 Windows Terminal。

若只有 prompt 图标是方块而普通中文正常,问题不是中文 locale,而是所选字体缺少 prompt 使用的专用 glyph。选择匹配 prompt 的字体或改用不依赖这些图标的主题。

3. 修复编码:不必为了显示中文强制使用中文 locale

显示中文只要求整条文本路径使用兼容的 Unicode/UTF-8 编码和有字形的字体,并不要求 LANG=zh_CN.UTF-8C.UTF-8en_US.UTF-8 或其他 UTF-8 locale 都可以显示中文;改为中文 locale 还会改变程序消息、日期和排序等行为。

locale charmap 已输出 UTF-8,不要仅为方块问题修改 /etc/default/locale。若 charmap 不是 UTF-8,可先选择不改变界面语言的 UTF-8 locale:

sudo update-locale LANG=C.UTF-8 LANGUAGE

若确实希望 Ubuntu 程序消息使用简体中文,先生成 locale,再通过 Ubuntu 的验证工具写入全局设置:

sudo apt update
sudo apt install --yes locales
sudo locale-gen zh_CN.UTF-8
sudo update-locale LANG=zh_CN.UTF-8 LANGUAGE=zh_CN:zh

不要持久设置 LC_ALL 来掩盖冲突;它会覆盖各个 LC_* 类别。update-locale 会检查值并更新 locale 配置,比手工在编辑器中输入智能引号更稳妥。

locale 修改只应在新 WSL 会话中验证。关闭需要保留的任务后,可从 PowerShell 停止所有 WSL 实例并重新打开发行版:

wsl --shutdown

这会终止所有正在运行的 WSL 发行版和进程,先保存工作。重新打开后再次运行 locale charmap 与中文测试。

4. 不要把 Windows 字体和 Linux 字体混为一谈

普通 Windows Terminal tab 使用 Windows 字体。2019 年正文安装的 ttf-wqy-microhei 是 Linux 包,通常不会修复 Windows Terminal 的字体选择。

Linux 字体在以下场景才相关:

  • WSLg 中运行的 Linux GUI 应用;
  • Linux 程序在 WSL 内部生成 PDF、图片或其他自行渲染的输出;
  • 某个 Linux 端渲染器明确通过 fontconfig 选择字体。

这种情况下先检查 fontconfig 的匹配结果:

fc-match 'sans-serif:lang=zh-cn'
fc-list :lang=zh-cn family | sed -n '1,20p'

若目标 Ubuntu 版本没有合适的 CJK 字体,可使用发行版包而不是不明下载:

sudo apt update
sudo apt install --yes fontconfig fonts-noto-cjk
fc-cache -f

安装后重启那个 Linux GUI/渲染应用。不要把这一步当作 Windows Terminal 方块的默认修复。

5. 只有一个文件或程序乱码时,检查它自己的编码

若测试字符串正常但旧日志、CSV 或源码异常,系统字体和全局 locale 很可能没有问题。保留原文件,然后确认生产者声明的编码;不要靠肉眼在 GBK、GB18030、Big5 和 UTF-8 之间猜测后覆盖原件。

可以先查看字节而不修改文件:

python3 - <<'PY'
from pathlib import Path

path = Path("sample.txt")
data = path.read_bytes()
print("first bytes:", data[:32].hex(" "))
print("UTF-8 preview:", data.decode("utf-8"))
PY

若 UTF-8 解码失败,错误位置是证据,不是立即修改全局 locale 的理由。查阅生成该文件的程序、协议或导出设置,确认源编码后转换到新文件并比较内容。例如仅在已经确认源文件是 GB18030 时:

iconv -f GB18030 -t UTF-8 legacy.txt > converted-utf8.txt

不要覆盖 legacy.txt,直到转换结果、行数和业务内容都已验证。

6. 用最小复现定位边界

按下表判断下一步:

结果 最可能的边界 下一步
PowerShell 与 WSL 中的中文都显示方块 Windows Terminal profile/font 检查所用 profile 的 Font face 与 Windows 字体安装
PowerShell 正常,WSL 的 UTF-8 测试为方块 WSL profile 可能覆盖字体,或使用了不同终端 host 确认 tab 对应的 profile 与 host
UTF-8 测试正常,单个文件乱码 文件或应用编码 保留原件,确认生产者编码后转换副本
locale charmap 不是 UTF-8 WSL locale update-locale 设置一个已安装的 UTF-8 locale,重新启动 WSL
普通中文正常,只有 prompt 图标方块 专用 glyph 缺失 更换匹配主题的字体或精简 prompt
Windows Terminal 正常,WSLg 应用方块 Linux fontconfig/GUI 字体 检查 fc-match,按发行版方式安装 CJK 字体

7. 验证与回退

完成一项修改后立即复测,不要堆叠修改:

printf '中文测试:你好,世界\n'
locale charmap
python3 -c 'print("Python 中文测试")'

验证这些事实:

  • 新开的 Windows Terminal tab 使用预期 WSL profile 和字体;
  • locale charmap 输出 UTF-8
  • shell、Python 和真正出问题的应用都能显示同一测试文本;
  • 英文、中文文件名及复制粘贴没有新增损坏;
  • WSLg 字体包只在确有 Linux 渲染需求时安装;
  • 修改前的 Terminal 配置和 locale 值已经记录,能够逐项回退。

相比 2019 年正文的变化

2019 年内容 2026 年维护方案
直接编辑 /etc/default/locale 先检查 charmap;需要修改时使用会校验输入的 update-locale
把中文显示与 zh_CN.UTF-8 绑定 说明任何合适的 UTF-8 locale 都能承载中文,界面语言是独立选择
安装 ttf-wqy-microhei 作为通用修复 区分 Windows Terminal 字体与 WSLg/Linux fontconfig 字体
未区分方块和乱码 分别定位 glyph 缺失、错误解码和无效字节
面向 2019 年 Windows 10 legacy host 维护层面向当前 WSL 与 Windows Terminal,同时保留历史背景
使用第三方文章作为唯一参考 维护层只使用 Microsoft、Ubuntu 和相关官方文档;旧链接仅存档

权威参考资料

Windows、WSL、Ubuntu 和 Terminal 的默认值会继续变化。最终以目标机器上安装版本的帮助和官方文档为准。

完整 2019 年正文(来源档案,请勿执行)


sudo vim /etc/default/locale

 LANG=zh_CN.UTF-8
 LANGUAGE=”zh_CN:zh”

 sudo apt-get install ttf-wqy-microhei

[https://blog.csdn.net/sethqqq/article/details/77017759](https://blog.csdn.net/sethqqq/article/details/77017759)

Leave a Reply