1. 方案背景:为什么要绕开图形界面配置中文
先简单交代一下来由。绝大多数人在Ubuntu上配中文,路径都是“设置 → 区域与语言 → 管理已安装的语言”,点几下鼠标,把“汉语”拖到第一位,然后等系统自动下载语言包,注销再登录就完事。这套流程在桌面版Ubuntu上确实好用,但有几个场景会让你非常被动:
- 你装的是Ubuntu Server,没有图形桌面,得靠纯命令操作;
- 桌面版存在,但“语言支持”入口老崩溃,或者因为系统版本问题,语言包下载永远卡在某个百分比;
- 你需要在Docker容器、云主机或者远程终端里快速把环境切到中文,根本没有点鼠标的机会;
- 更常见的情况:图形界面下改完语言,重启后有些第三方软件还是英文。这是因为系统级的环境变量根本没改干净,只改了桌面的显示语言。
在这种前提下,终端设置法就不是“备胎”了,而是最可靠、最彻底的手段。它本质上是直接修改系统的locale配置,把中文语言环境写进系统级配置文件里。图形界面操作的下层逻辑其实也是调这些配置文件,但终端方式让你能清楚地看到每一步到底改了什么,出了问题也好排查。
这篇文章适用的读者很明确:被语言问题折腾过的Linux新人、需要批量配置服务器的运维、想在容器里做中文环境的开发者,或者单纯想搞清楚“系统语言到底存在哪个文件里”的好奇派。看完之后你不仅能照抄命令,还能理解这些命令各自干了什么。
2. 动手前的三个准备工作
2.1 确认系统版本和字符编码现状
开始之前先看一眼当前系统的语言环境是什么样。在终端执行:
locale locale -a cat /etc/default/localelocale命令输出当前会话的语言变量,locale -a列出系统里已生成的全部locale,/etc/default/locale则是系统级默认配置文件。如果locale -a的输出里没有zh_CN.utf8这一项,说明系统压根没生成过中文locale,后面需要单独处理。这一步非常重要,因为它决定了你是“只需要切换”还是“需要先生成”。
有个小细节值得注意:不同Ubuntu版本对locale的命名略有差异。20.04及之前常见的是zh_CN.utf8,22.04以后多为zh_CN.UTF-8,两者在实际使用中等价,但写到配置文件里时最好以locale -a实际输出的名字为准,否则会出现“明明设置了却不生效”的怪现象。
2.2 更新软件源,确保语言包能拉到
终端方式配置中文,核心依赖是language-pack-zh-hans这个软件包。装包之前强烈建议先刷新软件源,避免装到旧版本或者因为索引过期导致找不到包:
sudo apt update如果是在国内服务器上操作,apt更新速度慢是家常便饭,可以顺手把软件源切换成国内镜像。这个属于可选优化项,不影响整体流程,但实测下来能节省大量等待时间。
2.3 准备切换时需要的包:中英文语言包缺一不可
这里是我踩过坑之后总结出的经验。很多人只装了中文包,结果系统切到中文后发现终端里有些系统提示变成了奇怪的方块或者乱码,反而更难受。正确的做法是确保英文语言包也在,因为locale的配置是支持同时存在多种语言的,切换时英文locale仍然可以作为回退选项保留:
sudo apt install language-pack-zh-hans language-pack-en如果想用繁体中文,把language-pack-zh-hans换成language-pack-zh-hant就行。但默认情况下简体中文环境就够了,繁体包通常不用装。
注意:不要在这里装一堆用不到的locale包,每多一个locale,系统运行
locale-gen时的生成时间就会肉眼可见地变长一些,对日常使用没有什么正收益。
3. 生成中文locale:让系统“认识”中文
3.1 locale文件的生成机制简述
先解释一个基础概念,不然你会觉得locale-gen这步很玄学。Linux系统里的locale并不是安装包时就自动生成好的,而是需要根据/etc/locale.gen文件里列出的清单来手动或半自动生成。可以把它理解成:你告诉系统“我提供了中文字符集的支持”,但系统还得先把每种语言的规则表编译出来,才能真正使用。
/etc/locale.gen是一个纯文本文件,里面按行列出了所有可用locale,大部分都被注释掉了。取消某一行开头的#注释,就等于告诉系统“我需要这个locale”,然后执行locale-gen,系统就会编译生成对应的locale数据。
3.2 实际操作:启用并生成zh_CN.UTF-8
用编辑器打开locale清单文件:
sudo nano /etc/locale.gen在文件里找到这一行:
zh_CN.UTF-8 UTF-8把行首的#去掉,保存退出。如果用的nano,按Ctrl + O回车保存,再按Ctrl + X退出。然后执行:
sudo locale-gen这时候系统会重新编译所有启用的locale,输出信息里能看到zh_CN.UTF-8... done之类的提示,说明中文locale已经生成成功了。你可以再用locale -a验证一下,应该能看到zh_CN.utf8出现在列表里。
不想手动编辑文件的话,也可以用一条命令直接完成启用和生成:
sudo locale-gen zh_CN.UTF-8这条命令会自动在/etc/locale.gen中启用对应的locale条目并执行生成。但我个人更推荐手动编辑文件的做法,因为你能直观看到系统里还有哪些locale可用,未来要加别的语言时心里也有数。
3.3 别把locale-gen和update-locale搞混
这是初学者最容易混的两个命令,作用完全不一样:
locale-gen:生成locale数据,让系统支持某种语言。update-locale:修改系统默认的locale配置,决定系统“用”哪种语言。
顺序上必须先执行locale-gen,再执行update-locale。反过来操作的话,系统可能报错,或者配置写了但找不到对应的locale数据,等于白写。
4. 修改系统级配置:三种方式各有利弊
4.1 直接修改/etc/default/locale文件
/etc/default/locale是Ubuntu系发行版存放系统默认语言设置的配置文件,环境变量的默认值就是从这里面读取的。打开看看:
cat /etc/default/locale初始内容通常就一行LANG="en_US.UTF-8",甚至可能没有这个文件(在某些最小化安装场景下)。直接修改它的内容:
sudo nano /etc/default/locale改成:
LANG=zh_CN.UTF-8 LC_ALL=zh_CN.UTF-8 LANGUAGE=zh_CN:zh关于LC_ALL这一条,我需要多讲几句。很多教程会告诉你别设置LC_ALL,因为它的优先级最高,会把所有分类项全部强制覆盖,以后你想单独改时间格式或数字格式会变得很麻烦。但我个人的经验是:在纯中文环境下,LC_ALL=zh_CN.UTF-8能让所有软件都老老实实显示中文,避免某些软件因为拿不到LC_MESSAGES的明确值而退回英文。如果之后有更细分的定制需求,再回来删掉LC_ALL那一行就行。
4.2 用update-locale命令修改(推荐)
手写文件容易出错,官方提供的update-locale命令是更稳妥的选择。它本质上就是帮你去编辑/etc/default/locale,但会做基本的参数校验:
sudo update-locale LANG=zh_CN.UTF-8 sudo update-locale LC_ALL=zh_CN.UTF-8 sudo update-locale LANGUAGE=zh_CN:zh也可以合并成一行:
sudo update-locale LANG=zh_CN.UTF-8 LC_ALL=zh_CN.UTF-8 LANGUAGE=zh_CN:zh执行完再检查一遍配置文件:
cat /etc/default/locale看到三行配置都在,就算成功了。这种方式的好处在于,即使写错了参数值,命令也会给出错误提示,不会像直接编辑文件那样容易留下一个连系统都读不懂的配置。
4.3 针对当前用户单独设置(仅影响当前会话)
如果只是想临时看看中文效果,不想动系统级配置,可以直接在当前shell里导出环境变量:
export LANG=zh_CN.UTF-8 export LC_ALL=zh_CN.UTF-8这种方式只在当前终端窗口生效,关闭终端就失效。适合临时体验、测试字符显示效果的场景。千万别把它当成一劳永逸的方案,我见过有人只在~/.bashrc里加了export语句,结果某些系统服务读取环境变量时根本不看用户级配置文件,导致系统日志还是英文,这就很让人头疼。
4.4 三种方式的对比速查表格
| 方式 | 生效范围 | 持久性 | 适用场景 | 风险等级 |
|---|---|---|---|---|
直接编辑/etc/default/locale | 全系统 | 永久 | 离线/极简环境下手动配置 | 中,需注意语法 |
update-locale命令 | 全系统 | 永久 | 标准服务器/桌面环境 | 低,推荐 |
export临时变量 | 当前终端 | 临时 | 快速测试、临时查看效果 | 极低 |
实际操作中,推荐把两种持久化方案结合:先尝试update-locale命令,如果系统老旧或命令行为异常,再改用手动编辑文件兜底。
5. 补一步收尾操作:让中文字体渲染不崩
5.1 为什么切完中文之后字体会发虚或变方块
刚切完中文的Ubuntu,最容易遇到的下一个坑就是字体问题。系统自带英文字体不认识汉字,而中文语言包只提供locale数据,并不会顺手帮你装上中文字体。界面上出现一个个方块(俗称“豆腐块”),就是这个原因。
解决办法是装中文字体包,常见的开源方案有:
sudo apt install fonts-noto-cjk这个包包含了思源黑体的CJK版本,是Linux生态里目前认可度最高的中日韩字体方案。它体积不小,大概几十MB,但装完之后无论终端还是桌面都能正常显示简体中文。如果只是命令行环境,装这个会有点“杀鸡用牛刀”的感觉,但胜在一劳永逸,后面装图形软件也不用再管字体问题了。
还有一个轻量选择是fonts-wqy-microhei(文泉驿微米黑),显示效果也不错,体积更小,适合配置较低的设备。
5.2 终端软件的特殊处理
用SSH远程登录服务器时,本地终端软件如果字符编码没对齐,服务器切了中文还是白搭。比如你用XShell或者MobaXterm连接,需要把终端编码设置为UTF-8,否则看到的中文就是乱码。这个问题非常常见,但很多人第一反应是“服务器配错了”,反复重配locale好几遍,最后才发现是本地终端窗口的问题。
5.3 重启还是注销?
配置和字体都处理完之后,需要让环境变量重新加载。有两个选择:
- 注销后重新登录(轻量,推荐日常使用)
- 重启整机(确认无误后的最终手段)
桌面版Ubuntu注销一下就行,速度快。服务器上没有图形界面的话,可以直接断开SSH再重新连接,效果等同于重新登录。重启属于“压箱底”的操作,一般不到万不得已不用,因为重启时间长,而且有些云主机重启后还会遇到其他服务依赖问题。
6. 实操过程复盘:一份可以直接抄的完整命令序列
为了让你照着做时不迷路,我把上面所有步骤整理成一份完整、干净的终端操作序列。你在终端里复制粘贴执行即可,每步的说明我都放在后面:
# 第一步:查看当前locale状态 locale locale -a # 第二步:更新软件源 sudo apt update # 第三步:安装中文语言包和字体 sudo apt install -y language-pack-zh-hans fonts-noto-cjk # 第四步:生成中文locale sudo locale-gen zh_CN.UTF-8 # 第五步:检查生成结果 locale -a | grep zh_CN # 第六步:修改系统默认配置 sudo update-locale LANG=zh_CN.UTF-8 LC_ALL=zh_CN.UTF-8 LANGUAGE=zh_CN:zh # 第七步:确认配置文件内容 cat /etc/default/locale # 第八步:重新登录或重启 logout执行完前七步之后,在终端里输入locale应该能看到LANG=zh_CN.UTF-8赫然在列,而不是之前的en_US.UTF-8。到了这一步,整个切换过程的命令层面就已经全部完成了。
这份命令序列看起来平平无奇,但它是无数次试错后沉淀下来的精简版。我最终固定下来的顺序是“先装包、再locale-gen、最后update-locale”,这个顺序遵循了依赖关系:语言包提供locale定义文件,locale-gen把定义编译成可用数据,update-locale把默认语言指向最终生成的数据。每一步都在给下一步铺路,颠倒顺序就会出各种奇怪的问题。
7. 常见问题与排查技巧实录
7.1 改了配置但locale输出还是英文
这种情况最典型。排查思路从简单到复杂依次排查:
- 当前shell是否加载了新配置?重新登录再执行
locale命令看看。 /etc/default/locale文件内容是否真的是中文配置?检查有没有写错编码名,比如写成zh_CN.UTF-8但系统里生成的是zh_CN.utf8,大小写不匹配会导致读取失败。- 是否存在
~/.bashrc或~/.profile里覆盖了系统级的locale设置?用户级配置文件里如果写了export LANG=en_US.UTF-8,优先级会高于系统级。用grep LANG ~/.bashrc ~/.profile查一下。 - SSH服务是否有独立的locale配置?少数情况下
/etc/ssh/sshd_config里设置了AcceptEnv LANG,会接受客户端传来的环境变量,覆盖服务器端配置。这时需要在客户端那边调整编码设置,或者在服务端把AcceptEnv LANG注释掉。
7.2 中文显示成方框
原因基本都在字体。用fc-list :lang=zh命令查看系统里有哪些支持中文的字体。输出为空就说明一个中文字体都没有,装一个fonts-noto-cjk即可。已经装了字体还显示方框的话,检查有没有设置/etc/fonts/config里对中文的优先级调整,这个属于进阶操作,日常不太用到。
7.3 装完语言包后locale-gen输出一堆错误
看到类似failed to write或者cannot open locale definition的报错,先运行sudo apt install --reinstall language-pack-zh-hans重装一遍语言包,然后再执行locale-gen。大部分情况下是语言包文件不完整,或者是软件源镜像滞后导致的版本错乱。我遇到过一回,排查到最后发现是镜像源里语言包和系统版本不匹配,干净重装后才正常。
7.4 部分程序界面还是英文
这是最常被人吐槽的情况。原因在于不少软件会读取LANGUAGE变量而不是LANG变量,或者两个都读取但优先级不同。我在前面的配置里特意加了一行LANGUAGE=zh_CN:zh,就是为了覆盖这个情况。如果还不行,检查这个软件的配置文件里是否自带语言选项,例如有些Java系软件会在~/.bashrc里显式指定过-Duser.language=en。
用表格速查一下以上问题的定位方向:
| 现象 | 首要排查点 | 次要排查点 |
|---|---|---|
| 配置生效但仍是英文 | 用户级配置文件覆盖 | SSH环境变量传递 |
| 中文显示方框 | 中文字体缺失 | fontconfig配置异常 |
| locale-gen报错 | 语言包损坏 | 软件源版本错配 |
| 部分软件保持英文 | LANGUAGE变量未设置 | 软件自身语言选项 |
8. 实战心得:什么时候用终端方法最划算
在你已经能熟练运用终端设置中文之后,有一个更上层的判断问题也值得聊两句:到底什么时候该用终端方法,什么时候用图形界面更合适?
先说我自己的倾向。如果是家里或者办公室的桌面Ubuntu,只有一两台机器,图形界面确实方便,五分钟搞定,不用记命令。但如果遇到这些场景,终端方法是无可替代的:
- 批量配置多台服务器,逐台点鼠标要疯的;
- 通过SSH远程配置无桌面环境的机器;
- 写自动化部署脚本,语言设置要可重复执行;
- 桌面环境本身出了问题,图形配置入口打不开;
- 需要精确控制locale的每个维度(时间格式、数字格式、货币单位等),而不是笼统地“设置为中文”。
我曾在大概十台机器上做统一语言环境配置,脚本里把那六行命令写清楚,循环执行一遍,不到两分钟全部搞定。换作图形界面的话,每台机器至少要登录进去、打开设置、找到语言选项、下载语言包、注销再登录,这个时间成本完全不是一个量级。
还有一点经验分享:在容器环境里配置中文,步骤和物理机完全一致,但要注意容器基础镜像里可能连sudo都没有,需要先以root身份操作,并且要确认镜像里有没有locales这个基础包,没有的话先apt install -y locales。这部分属于衍生技巧,但踩过坑的人都懂它的重要性。
9. 最后补充一个小技巧:如何把配置恢复成英文
配置中文不是单向操作,未来如果换给英文用户使用,或者某些服务在中文环境下出现兼容问题,随时可以切回去。恢复英文的命令同样简单:
sudo update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LANGUAGE=en_US:en如果系统中没有生成en_US.UTF-8的locale数据,先补一条sudo locale-gen en_US.UTF-8。恢复操作和设置中文完全对称,不需要重新安装任何语言包,因为英文locale在绝大多数Ubuntu安装中都是默认就存在的。这条退路可以让你放心大胆地折腾,反正随时能回滚。
从我个人小幅总结来说,用终端配置中文这件事,本身不难,难点在于搞清楚每一步背后的逻辑链条,理解了locale-gen和update-locale的分工,你就不容易在各类报错面前抓瞎。而且这套方法论不止适用于中文,将来想配日文、韩文、法文,无非是换一下语言代码的事,整个操作框架完全通用。