前言
很多运维会遇到一个很迷惑的问题:在 MySQL 命令行里,中文明明能正常显示,但是用鼠标复制出来粘贴到本地,中文直接是空、看不见汉字;修改 LANG=zh_CN.UTF-8 时又报错:-bash: warning: setlocale: LC_ALL: cannot change locale (zh_CN.UTF-8)。
这个问题根源分两块:系统 Locale 缺失 / 编码不对、MySQL 客户端连接字符集不匹配,另外 SSH 终端本身编码也是高频踩坑点。本文整理完整排查和修复方案,覆盖 CentOS7 / CentOS8 / CentOS Stream。
一句话结论:优先使用 en_US.UTF-8,不需要中文语言包也能正常承载 UTF8 中文;非要 zh_CN.UTF-8 再单独安装语言包
现象汇总
- MySQL 终端查询,屏幕上中文可见,复制粘贴后中文为空、只有符号和数字
- 执行
export LANG=zh_CN.UTF-8,bash 警告:cannot change locale (zh_CN.UTF-8) show variables like 'character%'看到character_set_client/character_set_results是 latin1
一、快速排查第一步:查看当前系统编码
locale
locale -a | grep UTF-8
最小化安装的 CentOS 默认往往是 LANG=C,没有加载 UTF-8 字符集,剪贴中文直接异常。
方案 1:推荐方案|使用 en_US.UTF-8(无警告、最简单)
不需要安装中文包,运维首选,UTF-8 编码本身可以正常展示、复制中文,只是系统提示是英文。
临时生效(当前 SSH 会话)
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
设置完成后,重新登录 MySQL 测试复制中文。
永久设置(CentOS8/Stream)
localectl set-locale LANG=en_US.UTF-8
CentOS7 永久设置
echo 'LANG=en_US.UTF-8' > /etc/locale.conf
source /etc/locale.conf
提示:source 不一定完全生效,断开 SSH 重新连接服务器是最稳妥的方式
方案 2:需要 zh_CN.UTF-8|安装中文 Locale 包
适合你希望系统提示信息也是中文的场景,CentOS8 / Stream 使用 dnf,CentOS7 使用 yum。
CentOS 8 / CentOS Stream
dnf install -y glibc-langpack-zh
安装完成后验证 locale 是否存在:
localectl list-locales | grep zh_CN
输出包含 zh_CN.UTF-8 代表成功。
设置默认 locale:
localectl set-locale LANG=zh_CN.UTF-8
CentOS7
yum install -y kde-l10n-Chinese glibc-common
localedef -c -i zh_CN -f UTF-8 zh_CN.UTF-8
设置变量:
export LANG=zh_CN.UTF-8
export LC_ALL=zh_CN.UTF-8
⚠️ 重要:修改 locale 配置之后,务必重连 SSH 会话,单纯 source 经常存在残留缓存,编码不生效。
二、MySQL 客户端字符集配置(核心,很多人只改系统 locale)
系统编码正常了,如果 MySQL 连接字符集是 latin1,复制中文依旧会丢失。
登录 MySQL 执行查看:
show variables like 'character%';
重点关注:
character_set_clientcharacter_set_connectioncharacter_set_results
临时修复(当前 MySQL 连接生效)
SET NAMES utf8mb4;
优先 utf8mb4,支持全部中文和 emoji;MySQL 里的 utf8 是 3 字节残缺版本,不推荐。
my.cnf 永久配置
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci
保存后重启 MySQL:
systemctl restart mysqld
三、容易被忽略:SSH 客户端本身编码
Xshell / FinalShell / SecureCRT 这类工具,终端编码必须设置为 UTF-8,不要 GBK、ANSI。 同时字体选择支持中文的字体(Noto Sans Mono、微软雅黑等),缺少中文字体也会导致复制出来空白。
四、兜底方案:绕过终端剪贴板 BUG(生产强烈推荐)
交互式 mysql 命令行的剪贴板在部分终端下有底层 bug,无论怎么调编码都会复制丢中文,直接导出文件是最稳的方案:
mysql -uroot -p --default-character-set=utf8mb4 -e "这里放你的SQL语句" > sql_result.txt
然后下载 sql_result.txt 文件,文件内中文不会丢失。
完整排查顺序(照着走)
- SSH 客户端编码 → 设置 UTF-8
- 服务器设置
LANG=en_US.UTF-8测试复制(优先,无依赖) - MySQL 登录后执行
SET NAMES utf8mb4;,再查询复制 - 上面方案无效,使用导出文件的方式绕开终端剪贴板问题
- 确有需要中文系统提示,再安装 glibc-langpack-zh 启用 zh_CN.UTF-8
补充踩坑小结
- 不要执着 zh_CN.UTF-8,运维场景 en_US.UTF-8 足够,坑更少
- source locale.conf 不等于重连 SSH,编码缓存经常坑人
- 屏幕能看见中文 ≠ 字符集是正确的,显示和剪贴板是两套逻辑
SET NAMES只对当前连接生效,想要长期生效一定要改 my.cnf