终端中文乱码需系统locale、终端解码方式、中文字体三者统一为utf-8:先用locale -a确认zh_cn.utf-8存在,再在~/.zshrc中设lang和lc_all,接着检查终端编码设置及fc-list :lang=zh验证字体。

终端文本输出中文显示乱码,**不是改个 LANG 就能解决的**。真正起作用的是三者必须同时对齐:系统 locale、终端模拟器的解码方式、终端所用字体是否含中文字形。漏掉任意一环,都会出现 ????、测试 或 □□□。
确认系统是否真有 zh_CN.UTF-8 这个 locale
很多人 export LANG=zh_CN.UTF-8 后没效果,是因为系统压根没生成这个 locale。它不是“设了就有”,而是得先让系统知道它存在:
- 运行
locale -a | grep zh_CN,如果输出为空或只有zh_CN.GB18030,说明还没生成 - Debian/Ubuntu:编辑
/etc/locale.gen,取消注释zh_CN.UTF-8 UTF-8,再执行sudo locale-gen - RHEL/CentOS:执行
sudo localedef -c -i zh_CN -f UTF-8 zh_CN.UTF-8(注意-c参数不能省,否则静默失败) - 再跑一次
locale -a | grep zh_CN,确认看到的是zh_CN.utf8(小写 utf8,带点号)——设置时必须严格匹配这个名称
只对交互式 shell 生效,别污染 cron 和 systemd
直接改 /etc/environment 或 /etc/profile 会让非交互式服务(比如 cron 脚本、systemd unit)也继承 zh_CN.UTF-8,可能引发日志解析失败、grep 匹配异常等问题:
- 在
~/.bashrc或~/.zshrc末尾加两行:export LANG=zh_CN.UTF-8export LC_ALL=zh_CN.UTF-8 - 执行
source ~/.bashrc(或对应配置文件) - 新开终端后运行
locale,确认LANG和LC_CTYPE都是zh_CN.UTF-8,且LC_ALL不为空
终端模拟器自身必须设为 UTF-8 解码
即使系统 locale 完全正确,终端若用 GBK 或 ISO-8859-1 去解码 UTF-8 字节流,照样显示乱码。这不是系统问题,是终端自己的设置:
- GNOME Terminal:菜单 → Preferences → Profile → Text → Character encoding → 选
Unicode (UTF-8) - Windows Terminal(连 WSL 或 SSH):设置 JSON 中加
"locale": "zh_CN.UTF-8",并确保"fontFace"是含 CJK 字形的字体(如Cascadia Code PL、Noto Sans CJK SC) - PuTTY / Xshell / FinalShell:进 Translation 或字符编码设置页,把
Remote character set明确设为UTF-8,不是 “Use font encoding” 或 “Auto”
检查字体是否真支持中文
locale 和终端编码都对了,但屏幕上还是空白或方块,大概率是字体缺失:
- 运行
fc-list :lang=zh,有输出才说明系统已加载中文字体 - 没输出?手动安装:
Debian/Ubuntu:sudo apt install fonts-wqy-microhei fonts-noto-cjk
RHEL/CentOS:sudo yum install wqy-microhei-fonts noto-cjk - 某些终端(如 Xshell)还需在【文件】→【属性】→【字体】里手动选一个支持中文的字体,比如
DejaVu Sans Mono或WenQuanYi Zen Hei
最容易被忽略的是:SSH 客户端默认会把自己的 LANG 发送给服务器,覆盖你设好的值。如果 ssh -v user@host 日志里出现 debug1: Sending env LANG = en_US.UTF-8,就得去服务器上禁用 AcceptEnv LANG LC_* 并重启 sshd。这个坑不排查,前面所有操作都白做。











