locale 决定什么
locale 决定系统使用哪种字符编码、语言、排序与日期格式。中文乱码基本都是「写入时是一个编码、读取时按另一个编码解释」的结果。排查要分三层看:系统是否已生成对应 locale(locale -a)、会话里 LANG 与 LC_* 实际取到什么值(locale)、以及应用或 JVM 是否自带编码设置覆盖了系统值。
基本信息
| 三层检查 | locale -a(是否生成)、locale(会话生效值)、应用自身设置 |
|---|---|
| 优先级 | LC_ALL > LC_* > LANG,排查先看 LC_ALL |
| 关键变量 | LANG、LC_ALL、LC_CTYPE(影响字符分类与编码) |
| JVM 相关 | file.encoding、sun.jnu.encoding |
| 持久化 | 写入 /etc/locale.conf 或用户 profile,临时 export 只对当前会话有效 |
典型使用场景
- 业务页面或终端出现中文乱码、问号、方块
- 中文排序(按拼音或笔画)结果与预期不符
- Java 应用读取文件或写日志时中文乱码
- 迁移来的脚本自带 LANG 设置,导致行为与预期不一致
- 新装信创系统后确认默认编码是否为 UTF-8
检查与设置
检查与设置
locale # 当前 LANG 与各 LC_* 的实际取值
locale -a | grep -i zh_CN # 系统是否已生成中文 locale
localectl status # 系统级 locale 与键盘配置
cat /etc/locale.conf 2>/dev/null # 持久化配置文件内容
export LC_ALL=zh_CN.UTF-8 # 临时对齐,仅当前会话有效
java -XshowSettings:properties -version 2>&1 | grep -iE 'encoding|locale'
java -Dfile.encoding=UTF-8 -jar app.jar # 启动参数级覆盖(按应用实际情况选择)现象与根因对照
| 现象 | 常见根因 | 确认方式 |
|---|---|---|
| 终端中文显示为问号 | LC_ALL 或 LC_CTYPE 指向非 UTF-8 | 逐项核对 locale 输出 |
| 只有一个应用乱码 | 应用或 JVM 自带编码设置 | 查应用配置与启动参数 |
| locale -a 里没有中文 | 系统未生成对应 locale | 补齐语言包后重新生成 |
| 换用户登录就正常 | 该用户 shell 配置里改过 LANG | 对比两个用户的 profile |
「系统是 UTF-8 但界面乱码」几乎总在应用层:应用自己写了编码设置,或读写了非 UTF-8 的存量文件。逐层看实际生效值,比反复改系统配置有效得多。
改系统 locale 会影响全机应用的编码与排序行为:生产环境调整前先在测试环境验证,并记录改动前的取值便于回退。