维护说明(2026 年 9 月 1 日):本页现在先提供适用于当前 WSL 与 Windows Terminal 的分层排查方法。文末保存完整的 2019 年正文,仅规范化行尾空白;其中手工编辑 locale、安装旧 Linux 字体包和第三方参考链接只属于历史记录,不是现行依据。
“中文方块”和“乱码”看起来相近,根因却不同:
□□□或空心方框通常表示终端所选字体没有对应 glyph;䏿–‡一类字符通常表示 UTF-8 字节被按错误编码解读;�通常表示输入含有无法按当前解码方式解释的字节。
先确定问题发生在 Windows 终端渲染、WSL locale,还是某个文件/程序的编码。不要同时更换字体、locale 和应用配置,否则即使恢复也很难知道真正原因。
Table of Contents
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 中:
- 按
Ctrl+,打开 Settings; - 选择实际使用的 Ubuntu/WSL profile;
- 打开 Appearance;
- 查看 Font face,并选择已安装、确认含有简体中文字形的字体;
- 新开一个 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-8。C.UTF-8、en_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 和相关官方文档;旧链接仅存档 |
权威参考资料
- Microsoft WSL 排障:版本信息、更新和 display language
- Microsoft WSL 基本命令
- Microsoft Windows Terminal 概览:Unicode 与 UTF-8 支持
- Microsoft Windows Terminal profile 外观与字体设置
- Microsoft Windows Terminal 安装和 Settings UI
- Microsoft Windows 字体管理
- Microsoft Typography:Microsoft YaHei 字体
- Microsoft Windows Terminal 自定义 prompt:缺失 glyph 的诊断
- Ubuntu `locale` 手册
- Ubuntu `locale-gen` 手册
- Ubuntu `update-locale` 手册
- Ubuntu `fonts-noto-cjk` 软件包
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)
