适用:Kylin 系列(桌面版/服务器版)、常见 Linux 发行版
用途:运维排障参考 / 技术博客素材
更新日期:2026-08
一、现象分类:先看乱码长什么样
终端中文显示异常,绝大多数可以从"乱码的样子"直接判断根因方向:
| 乱码形态 | 特征 | 根因方向 |
|---|---|---|
| □ 方块 / 豆腐块 | 汉字变成空心方块或 "□" | 字体缺 CJK 字形(最常见) |
| 下划线 "_" | 整行中文全部变下划线 | tmux 判定客户端不支持 UTF-8 |
| 乱符号(如 鈥媯/浜?) | 一堆不可读字符 | 编码错位(GBK/UTF-8 混用) |
| � 替换符 | 单个黑色问号方块 | 字节被截断/非法 UTF-8 |
| 中文消失/选中才显示 | 平时看不到,鼠标选中能看到 | opencode/TUI 渲染 bug |
本次实战案例:银河麒麟 V10 下 opencode 界面中文显示方块,即第一类------字体问题。
二、第一优先级排查:基础三项
无论乱码形态如何,先确认环境基础没问题:
bash
# 1. locale 必须是 UTF-8
locale
# 期望输出 zh_CN.UTF-8(或 en_US.UTF-8 等含 .UTF-8 的值)
# 2. 系统是否有中文字体
fc-list :lang=zh | head
# 空输出 = 没有中文字体,装 fonts-noto-cjk
# 3. 终端里直接打印中文验证
echo "中文显示测试"
# 正常 → 问题在应用层(opencode/TUI)
# 方块 → 终端字体/渲染问题
# 乱符号 → 编码问题
按发行版装中文字体:
bash
# 银河麒麟/Ubuntu/Debian
sudo apt install -y fonts-noto-cjk # Kylin 桌面版
# 银河麒麟服务器版(yum/dnf 系)
sudo dnf install -y fonts-noto-cjk # 或 google-noto-cjk
# 验证安装
fc-list :lang=zh | head
三、分类排查
情况 A:方块 / 豆腐块 → 终端字体没有 CJK 字形
根因 :终端模拟器的字体没指到中文字体,或者没启用非 ASCII 回退。
(系统装了 Noto CJK 也可能没用------终端配置里的字体才是渲染用的)
解决:
-
Linux 桌面终端(GNOME Terminal / 麒麟自带终端 / Konsole)
首选项 → 配置文件 → 字体 → 选 Noto Sans Mono CJK SC(或宋体/楷体)
-
iTerm2 (macOS)
Preferences → Profiles → Text → 勾选
"Use a different font for non-ASCII characters",选 PingFang SC / Noto Sans CJK SC
-
远程连接时:SSH 客户端(如 Windows Terminal / Xshell)也要改字体,服务器装字体没用
判断技巧:方块是"字体缺字形",不是"字符传丢了"。
用鼠标复制乱码文本粘到文本编辑器,如果显示正常中文 → 100% 是终端渲染层问题。
情况 B:全是下划线 "_" → tmux 判定客户端不支持 UTF-8
特征 :直接在终端运行 opencode 正常,进 tmux 就全变下划线。
根因 :tmux client 判定外层终端不支持 UTF-8 输出(client_utf8=0),
保守策略把非 ASCII 字符替换成下划线。与字体、opencode 都无关。
验证:
bash
tmux display-message -p 'client_termname=#{client_termname} client_utf8=#{client_utf8}'
# client_utf8=0 就是根因
解决:
bash
# 新开会话用 -u 强制 UTF-8
tmux -u new -s work
# 已存在会话:先 detach(Ctrl-b d),再
tmux -u attach -t work
固化配置(~/.tmux.conf):
set -g default-terminal "tmux-256color"
set-environment -g LANG "en_US.UTF-8"
set-environment -g LC_CTYPE "en_US.UTF-8"
注意:
source ~/.tmux.conf只影响后续新 pane;已连接的 client 必须 detach 重连才生效。
情况 C:乱符号 / 编码错位 → 字符编码不一致
特征:非 ASCII 字符显示为 鈥媯/浜? 之类,ASCII 正常。
根因:写入端用 UTF-8,读取端按 GBK(或反之)解码。常见于:
- Windows 中文系统(代码页 936/GBK)跑 Linux 风格工具
- Windows 上执行命令回显(
chcp不是 65001) - opencode bash 工具在 Windows 上解码硬编码 utf-8
验证(Windows):
cmd
chcp
:: 936 就是 GBK,需切到 65001
chcp 65001
解决(Windows):
cmd
:: 每次会话执行
chcp 65001 >nul
:: 或 Python 子进程强制 UTF-8
set PYTHONUTF8=1
set PYTHONIOENCODING=utf-8
:: 或 PowerShell 5.1
$OutputEncoding = [Console]::OutputEncoding = [Text.UTF8Encoding]::new($false)
Linux/macOS:检查 locale 是否被某个进程污染成非 UTF-8:
bash
env | grep -E 'LANG|LC_'
# 期望含 .UTF-8;如有 LANG=C 或 zh_CN.GBK 则修正
export LANG=zh_CN.UTF-8
export LC_ALL=zh_CN.UTF-8
情况 D:中文在 opencode/TUI 里消失或错位
特征:菜单/界面中文看不见,鼠标选中能看见;或中文被截断、错位。
根因 :TUI 框架的 CJK 字符宽度计算问题(宽字符被当成单宽),
或特定 opencode 版本的渲染 bug(如 v1.1.13 曾出现,升级/降级即恢复)。
解决:
bash
# 升级/降级 opencode
opencode upgrade
# 或换一个终端模拟器验证(Alacritty / VS Code 终端等)
# 部分用户反馈换主题也能规避(system 主题有问题,ayu 正常)
四、本次实战案例(银河麒麟 + opencode 方块问题)
现象:opencode 界面中文全显示方块。
排查过程:
locale→zh_CN.UTF-8,正常fc-list :lang=zh→ 已装 google-noto-cjk,正常echo "中文显示测试"→ 正常 → 排除编码,定位为终端渲染TERM=xterm-256color→ 正常- 结论:终端模拟器字体配置未包含 CJK 字形
解决:终端字体改为 Noto Sans Mono CJK SC,重启终端/opencode 后正常。
关键经验:系统有字体 ≠ 终端用这个字体。终端字体列表需要自己选。
五、排障流程图
中文乱码
│
├─ echo "中文" 显示正常?
│ 是 → 应用层(opencode/TUI)→ 升级/换终端/换主题
│ 否 ↓
├─ 方块/豆腐?
│ 是 → 终端字体无 CJK → 换 Noto Sans Mono CJK SC
│ 否 ↓
├─ 全是下划线?
│ 是 → tmux client_utf8=0 → tmux -u
│ 否 ↓
└─ 乱符号/编码错位?
是 → 检查 chcp / locale → 统一 UTF-8
六、常用命令速查
bash
locale # 查看当前语言环境
fc-list :lang=zh # 列出中文字体
fc-match "Noto Sans Mono CJK SC" # 检查终端字体是否命中
tmux display-message -p 'client_utf8=#{client_utf8}' # tmux UTF-8 状态
env | grep -E 'LANG|LC_' # 环境变量
chcp # Windows 代码页
附:本次实战环境信息
| 项目 | 值 |
|---|---|
| 系统 | Kylin Linux Advanced Server V10 (Halberd) |
| 架构 | x86_64 |
| locale | zh_CN.UTF-8 |
| 字体 | google-noto-cjk 已安装 |
| 终端 | xterm-256color |
| 应用 | opencode 1.18.13 |