把 DietPi 刷到开发板上,折腾了一天,系统跑起来了。你想打开一个中文文件名看看,结果屏幕上整整齐齐排了一串“□□□”和“????”,那一刻是真的会怀疑人生。我遇到过不止一次这种场面,而且每次帮别人排查时都会发现,很多人第一反应是“换系统”,其实没必要。Debian 系系统的 DietPi 只是默认没带中文字体而已,缺的其实就是一套通用中文字体包。今天这篇是这个“把海外系统逐步调教成适合中文环境使用”系列的第三篇,对应东方仙盟体系里的“练气期”,也就是最基础的入门阶段:先别想输入法、桌面美化和高级本地化,先把“中文能正常显示”这一件事做到位。
DietPi 不是不能显示中文,它是真的没有准备中文字库。所以这个阶段的核心任务非常明确:装一个面向通用环境的中文字体包。我会把原理、选型、实际操作步骤和踩过的坑一起讲完,看完你也能让你的 DietPi 变成一个不会看到满屏方块的中文友好系统。
1. 为什么 DietPi 装上中文就乱码:先弄懂“缺字体”和“编码错”是两回事
我见过很多新手在排查中文乱码时,把大量时间花在改 locale、改编码、改环境变量上,结果折腾半天下结论:“这个系统不支持中文。”其实它真的不是不支持,而是你根本还没把字库喂给它。先花点时间搞清楚乱码的来源,后面就不会乱撞了。
1.1 你以为的乱码,多半是“缺字形(tofu)”
很多人口中的“中文乱码”,实际上分两种完全不同的情况。第一种是编码错误,显示出来的是一堆看不懂的符号,比如 ä¸Âæ–‡ 这种,或者整片问号。这个属于语言环境(locale)和应用之间对字符编码的解读不一致,通常改一下 locale 或者终端编码就能解决。
第二种,也就是 DietPi 上最常见的情况,是编码本身没问题,文件确实被系统正确识别为中文,但系统里找不到任何一款能画出这些汉字的字体文件。于是字体渲染引擎就只能画一个占位方块出来,这个方块在排版圈有个专门的叫法:tofu,豆腐块。大家平时说的“中文全是方块”,其实不是乱码,而是字体层面的缺字,本质是字形缺失。
我自己判断这两种情况的土办法是:在终端里用 printf '中文测试\n' 输出一行中文,如果看到的是一串特奇怪的乱字符,那是编码问题;如果看到的是规规矩矩的方块,那就是字体问题。DietPi 一上来经常是后者,因为它是为轻量设备设计的精简系统,本着能省则省的原则,默认带的字体只覆盖拉丁字符和部分符号,CJK(中日韩统一表意文字)字体一个都没装。
1.2 fontconfig 回退机制:中文字库为什么必须是“通用包”
理解了豆腐块的来源,接下来要知道 Linux 桌面和应用是怎么决定用哪款字体来画你的字符的。大部分图形程序不会自己去翻字体文件,而是委托 fontconfig 这个字体配置与匹配库去选择。程序给出一个字体族名称,比如 sans-serif、serif、monospace,fontconfig 会在系统里按配置的优先级去找匹配的字体。这里有一个关键机制叫字体回退(fallback):当字体族列表里的第一个字体没有覆盖某个字符时,fontconfig 会继续往下找,直到找到一款包含该字符的字体。
问题就出在这里。DietPi 默认配置下,排在前面的往往是 DejaVu Sans、Liberation Sans 这类只覆盖拉丁字符的字体,它们对汉字无能为力。fontconfig 沿列表往下找,发现后面根本没有 CJK 字体可以顶上,于是直接交出一个空白,渲染引擎就画成豆腐块了。
所以这个阶段最该做的事,就是给系统安装一款覆盖面足够广的中文字体,让 fontconfig 在匹配失败时有路可退。这也是为什么我一直强调核心是“通用中文字体包”。“通用”两个字很关键:它必须是被广泛测试过,可以进入 fontconfig 的回退链条,能被 Qt/GTK 程序正常调用的系统级字体包,而不是你从某个地方下载的零散 ttf 文件。Debian 仓库里打包好的通用的中文字体包,装完就能自动被全系统识别,不用额外配置路径,这才是省心方案。
1.3 中文适配要两条腿走路:字体管渲染,locale 管语言
再延伸一句,把中文适配想成两条腿。第一条腿就是字体,解决的是“字符画不画得出来”,属于渲染层;第二条腿是 locale,解决的是“程序界面用什么语言显示、字符串怎么排序、时间格式长什么样”,属于运行时环境层。
装字体包,只解决了第一条腿。你装完之后,中文文件名能正常显示了,浏览器看中文网页也没问题了,但如果程序界面还是英文,那不是字体的锅,而是系统的 locale 还是英文,程序没有启用中文语言资源。DietPi 的软件源基于 Debian 体系,绝大多数桌面程序都带中文翻译文件,但系统没有把语言环境切到中文时,程序默认就走英文分支。
这也是为什么我建议字体包和 locale 同步做,不要装完字体就以为万事大吉。这篇的重点虽然是字体包,但我会在后面专门用一节讲 locale 和字体优
