Linux中文乱码需系统locale、终端解码、SSH传输、字体渲染四环节全部对齐UTF-8:先用locale和locale -a | grep zh_CN确认LANG/LC_ALL为zh_CN.UTF-8且已生成,再设用户级环境变量、客户端UTF-8编码及中文字体。

Linux 中文乱码不是改一个变量就能修好的问题,而是编码链上多个环节没对齐的结果:系统 locale 设置、终端解码方式、SSH 传输协议、字体渲染能力——任一环断掉,中文就显示成 ???、方块或问号。
先确认 locale 是否真正可用
别只看 echo $LANG,它可能只是个空值或错误值。真正要看的是:
→ 运行 locale,重点盯住 LANG、LC_CTYPE、LC_ALL 这三项是否为 zh_CN.UTF-8 或至少是 en_US.UTF-8;
→ 运行 locale -a | grep zh_CN,如果无输出,说明系统压根没生成中文 locale,后续所有 export 都会静默失败。
常见修复方式:
- Debian/Ubuntu:编辑 /etc/locale.gen,取消 zh_CN.UTF-8 UTF-8 前的注释,再执行 sudo locale-gen
- RHEL/CentOS/Rocky:运行 sudo localedef -c -i zh_CN -f UTF-8 zh_CN.UTF-8(注意 -c 参数不能省,否则不报错但也不生效)
- Arch Linux:编辑 /etc/locale.gen 后执行 sudo locale-gen,再写入 LANG=zh_CN.UTF-8 到 /etc/locale.conf
环境变量设置要讲优先级和作用域
LC_ALL 优先级最高,一旦设了,就会覆盖 LANG 和所有 LC_* 变量。调试时建议先 unset LC_ALL 排除干扰。
不推荐全局硬编码(比如在 /etc/environment 或 /etc/profile 里设),容易让 cron、systemd 服务也继承中文 locale,引发日志解析异常或脚本崩溃。
更稳妥的做法是只对交互式 shell 生效:
- 编辑 ~/.bashrc 或 ~/.zshrc,末尾添加:
export LANG=zh_CN.UTF-8
export LC_ALL=zh_CN.UTF-8
然后执行 source ~/.bashrc(或对应配置文件),新开终端后再次运行 locale,确认 LANG 和 LC_CTYPE 都是 zh_CN.UTF-8,且 LC_ALL 不为空。
SSH 连接必须确保两端编码一致
服务端 locale 对了,客户端没对齐,照样乱码。关键不在 Linux 端“改成中文”,而在“让客户端按 UTF-8 解码字节流”。
常见客户端设置:
- PuTTY:Window → Translation → Remote character set 选 UTF-8(不是 GBK,也不是 Automatic)
- SecureCRT:Options → Session Options → Appearance → Character Encoding 设为 UTF-8;Terminal → Emulation → Terminal 设为 xterm 或 linux
- Windows Terminal / WSL:设置 JSON 中加 "locale": "zh_CN.UTF-8",并确保 "fontFace" 使用含 CJK 字形的字体(如 Noto Sans CJK SC)
- OpenSSH(本地 PowerShell):连接前先运行 chcp 65001 切换代码页
还要确保 SSH 环境变量能透传:
- 本地 ~/.ssh/config 加一行:SendEnv LANG LC_*
- 远程服务器 /etc/ssh/sshd_config 加一行:AcceptEnv LANG LC_*
- 改完执行 sudo systemctl restart sshd
终端字体和编码设置不能漏
即使 locale 全对,终端用的字体不含汉字字形,结果就是 □□□ 或空白——这常被误判为编码问题。
验证中文字体是否就位:
→ 运行 fc-list :lang=zh,有输出才说明已加载中文字体
→ GNOME Terminal:编辑 → 首选项 → 当前配置文件 → 字体 → 勾选自定义字体,选 Noto Sans CJK SC 或 WenQuanYi Micro Hei
→ 终端编码设置也要统一为 UTF-8:GNOME Terminal 是 Text → Character encoding → Unicode (UTF-8)


















