先确认en_us.utf-8是否存在,若不存在需生成;再检查配置文件路径与格式是否匹配发行版要求;最后清除lc_all覆盖、禁用ssh环境变量透传,并验证locale输出。

直接改 LANG=en_US.UTF-8 很可能没用——系统根本没生成这个 locale,或者写错了配置文件位置,又或者被 LC_ALL 覆盖了。
先确认 en_US.UTF-8 是否真的存在
很多用户一上来就编辑配置文件,结果重启后还是中文,原因就是系统压根没这个 locale。必须先验证:
- 运行
locale -a | grep en_US.UTF-8—— 有输出才说明已就绪 - 没输出?说明要生成它:Debian/Ubuntu 执行
sudo dpkg-reconfigure locales,空格勾选en_US.UTF-8;CentOS/RHEL 8+ 运行sudo dnf reinstall glibc-langpack-en;Arch 用户需取消/etc/locale.gen中en_US.UTF-8 UTF-8的注释,再跑sudo locale-gen - 别信“装了 glibc 就一定有”——RHEL 8+ 默认不带英文语言包,得手动装;Debian 系若用最小化安装,
locales包甚至可能根本没装
写对配置文件,否则等于白改
不同发行版读取的主配置文件完全不同,写错路径或格式,LANG 就永远不会生效:
- CentOS/RHEL 7+、Fedora、Arch:只认
/etc/locale.conf,内容必须是LANG=en_US.UTF-8(无引号,单行) - Debian/Ubuntu:优先读
/etc/default/locale,格式为LANG="en_US.UTF-8"(带双引号) - RHEL 6 及更老系统:用
/etc/sysconfig/i18n,格式同上,但注意别拼错成/etc/syscnfig/i18n(常见手误) - 桌面环境(GNOME/KDE)会缓存旧设置,改完必须登出重进,或执行
sudo systemctl restart systemd-localed
为什么 SSH 登录后又变回中文?
因为 SSH 默认会把客户端的 LC_* 变量透传过来,服务端的 PAM 或 shell 启动脚本根本没机会生效:
- 检查
/etc/ssh/sshd_config是否有AcceptEnv LANG LC_*—— 如果有,客户端发来的值会直接覆盖你设的LANG - 临时绕过:在
~/.bashrc末尾加export LANG=en_US.UTF-8,并确保它在source链里靠后执行 - 根本解法:清空
LC_ALL(它优先级最高),运行unset LC_ALL或在配置中设LC_ALL=(空值) - 终端本身也要配 UTF-8:Xshell/FinalShell 需手动设 Remote character set 为 UTF-8;Windows 自带 OpenSSH 则需提前运行
chcp 65001
Java、Python 等程序仍显示乱码?
这些程序往往不继承系统 LANG,尤其 Java 默认忽略环境变量:
- Java 启动时必须显式指定:
java -Dfile.encoding=UTF-8 ...;Tomcat 在bin/catalina.sh加JAVA_OPTS="-Dfile.encoding=UTF-8" - Python 3 一般没问题,但若用
subprocess调外部命令,仍需在env参数里手动传入LANG=en_US.UTF-8 - 字体也得支持英文:运行
fc-list :lang=en应有输出;没有就装fonts-dejavu(Debian/Ubuntu)或dejavu-sans-fonts(RHEL/CentOS)
最常被跳过的其实是验证环节:改完别急着关终端,立刻跑 locale 和 locale -a | grep en_US.UTF-8,再开个新 SSH 连接测试——漏掉任意一步,LANG=en_US.UTF-8 就只是个安静躺在文件里的字符串。











