linux centos7.9 中文乱码
centos 7.9中毒清理完病毒之后中文乱码
CentOS 7.9日志显示乱码(如“??”)通常是由于系统缺少中文语言包或字符编码配置不当导致。以下是分步解决方法:
一、检查并安装中文语言包
查看已安装的语言包
执行以下命令,若输出中无 zh_CN 相关条目,说明未安装中文语言包:
bash
locale -a | grep "zh_CN"
正常输出为:
[root@localhost ~]# locale -a|grep "zh_CN"
zh_CN
zh_CN.gb18030
zh_CN.gb2312
zh_CN.gbk
zh_CN.utf8
安装中文语言包
通过 yum 安装必要的中文支持包:
bash
Copy Code
yum -y install kde-l10n-Chinese # 安装中文语言包:ml-citation{ref="1" data="citationList"}
yum reinstall glibc-common -y # 更新字符编码相关依赖:ml-citation{ref="1" data="citationList"}
生成中文编码
创建 zh_CN.utf8 编码环境:
bash
Copy Code
localedef -c -f UTF-8 -i zh_CN zh_CN.utf8 # -c 强制创建,-f 指定UTF-8编码:ml-citation{ref="1" data="citationList"}
二、配置系统默认字符编码
修改全局语言配置文件
编辑 /etc/locale.conf 文件,设置默认语言为中文UTF-8:
bash
Copy Code
echo 'LANG="zh_CN.UTF-8"' > /etc/locale.conf # 覆盖文件内容
source /etc/locale.conf # 立即生效(无需重启):ml-citation{ref="3" data="citationList"}
设置用户会话编码
在 /etc/profile 中添加环境变量,确保所有用户登录时应用编码:
bash
Copy Code
echo 'export LC_ALL=zh_CN.UTF-8' >> /etc/profile
source /etc/profile # 刷新配置:ml-citation{ref="1" data="citationList"}
三、针对日志文件的特殊处理(如Tomcat日志)
若特定服务(如Tomcat)的日志(如 catalina.out)仍乱码,需在服务启动参数中强制指定编码:
进入服务配置目录(以Tomcat为例):
bash
Copy Code
cd /usr/local/tomcat/bin # 替换为实际Tomcat路径
编辑启动脚本(catalina.sh 或 daemon.sh),添加JVM编码参数:
bash
Copy Code
JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8" # 设置文件编码:ml-citation{ref="4" data="citationList"}
重启服务使配置生效:
bash
Copy Code
systemctl restart tomcat # 或对应服务名
四、验证配置是否生效
检查系统当前编码:
bash
Copy Code
echo $LANG # 应输出 zh_CN.UTF-8
locale # 确认所有LC_*参数均为 zh_CN.UTF-8:ml-citation{ref="3" data="citationList"}
测试中文显示:
创建包含中文的测试文件并查看:
bash
Copy Code
echo "测试中文显示" > test.log
cat test.log # 若显示正常,说明配置生效
五、注意事项
编码兼容性:若部分场景仍乱码,可尝试其他中文编码(如 zh_CN.gb18030 或 zh_CN.gbk),修改 /etc/locale.conf 中的 LANG 值并重新加载配置。
容器环境:若在Docker容器中,需在构建镜像时预装语言包并配置编码(参考Dockerfile示例)。
通过以上步骤,可彻底解决CentOS 7.9系统及应用日志的中文乱码问题。
正常的/etc/profile文件内容:
[root@localhost ~]# cat /etc/profile
# /etc/profile
# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc
# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, as this
# will prevent the need for merging in future updates.
pathmunge () {
case ":${PATH}:" in
*:"$1":*)
;;
*)
if [ "$2" = "after" ] ; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
esac
}
if [ -x /usr/bin/id ]; then
if [ -z "$EUID" ]; then
# ksh workaround
EUID=`/usr/bin/id -u`
UID=`/usr/bin/id -ru`
fi
USER="`/usr/bin/id -un`"
LOGNAME=$USER
MAIL="/var/spool/mail/$USER"
fi
# Path manipulation
if [ "$EUID" = "0" ]; then
pathmunge /usr/sbin
pathmunge /usr/local/sbin
else
pathmunge /usr/local/sbin after
pathmunge /usr/sbin after
fi
HOSTNAME=`/usr/bin/hostname 2>/dev/null`
HISTSIZE=1000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
export HISTCONTROL=ignoreboth
else
export HISTCONTROL=ignoredups
fi
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL
# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
# /usr/share/doc/setup-*/uidgid file
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
umask 002
else
umask 022
fi
for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
if [ -r "$i" ]; then
if [ "${-#*i}" != "$-" ]; then
. "$i"
else
. "$i" >/dev/null
fi
fi
done
unset i
unset -f pathmunge
# CentOS 7 语言配置文件
cat /etc/locale.conf
# 检查profile中的语言变量(若有自定义)
grep -i "LANG\|LC_ALL" /etc/profile /etc/profile.d/*.sh
[root@localhost ~]# grep -i "LANG\|LC_ALL" /etc/profile /etc/profile.d/*.sh
/etc/profile.d/lang.sh:# /etc/profile.d/lang.sh - set i18n stuff
/etc/profile.d/lang.sh:if [ -n "$LANG" ]; then
/etc/profile.d/lang.sh: saved_lang="$LANG"
/etc/profile.d/lang.sh: LANG="$saved_lang"
/etc/profile.d/lang.sh: unset saved_lang
/etc/profile.d/lang.sh: for langfile in /etc/locale.conf "$HOME/.i18n" ; do
/etc/profile.d/lang.sh: [ -f $langfile ] && . $langfile && sourced=1
/etc/profile.d/lang.sh: [ -n "$LANG" ] && export LANG || unset LANG
/etc/profile.d/lang.sh: if [ -n "$LC_ALL" ]; then
/etc/profile.d/lang.sh: if [ "$LC_ALL" != "$LANG" ]; then
/etc/profile.d/lang.sh: export LC_ALL
/etc/profile.d/lang.sh: unset LC_ALL
/etc/profile.d/lang.sh: unset LC_ALL
/etc/profile.d/lang.sh: [ -n "$LANGUAGE" ] && export LANGUAGE || unset LANGUAGE
/etc/profile.d/lang.sh: if [ -n "$LANG" ]; then
/etc/profile.d/lang.sh: case $LANG in
/etc/profile.d/lang.sh: case $LANG in
/etc/profile.d/lang.sh: ja*) LANG=en_US.UTF-8 ;;
/etc/profile.d/lang.sh: ko*) LANG=en_US.UTF-8 ;;
/etc/profile.d/lang.sh: si*) LANG=en_US.UTF-8 ;;
/etc/profile.d/lang.sh: zh*) LANG=en_US.UTF-8 ;;
/etc/profile.d/lang.sh: ar*) LANG=en_US.UTF-8 ;;
/etc/profile.d/lang.sh: fa*) LANG=en_US.UTF-8 ;;
/etc/profile.d/lang.sh: he*) LANG=en_US.UTF-8 ;;
/etc/profile.d/lang.sh: *_IN*) LANG=en_US.UTF-8 ;;
/etc/profile.d/lang.sh: case $LANG in
/etc/profile.d/lang.sh: ja*) LANG=en_US ;;
/etc/profile.d/lang.sh: ko*) LANG=en_US ;;
/etc/profile.d/lang.sh: si*) LANG=en_US ;;
/etc/profile.d/lang.sh: zh*) LANG=en_US ;;
/etc/profile.d/lang.sh: ar*) LANG=en_US ;;
/etc/profile.d/lang.sh: fa*) LANG=en_US ;;
/etc/profile.d/lang.sh: he*) LANG=en_US ;;
/etc/profile.d/lang.sh: *_IN*) LANG=en_US ;;
/etc/profile.d/lang.sh:unset langfile
/etc/profile.d/vte.sh: LC_ALL=C
从查询结果来看,服务器已安装中文语言包和字符集相关组件,但存在glibc-common重复安装的情况(两个不同版本),可能导致配置冲突。以下是针对性处理步骤:
一、清理重复的glibc-common包
查看已安装版本优先级
bash
Copy Code
rpm -qi glibc-common-2.17-326.el7_9.3.x86_64 | grep "Install Date" # 确认新版本安装时间
通常高版本(el7_9.3)会覆盖低版本(el7_9),但残留旧版本可能导致配置文件冲突。
卸载低版本包
bash
Copy Code
yum remove -y glibc-common-2.17-326.el7_9.x86_64 # 仅卸载旧版本,保留新版本
二、重新生成字符集并刷新配置
强制重新生成zh_CN.UTF-8字符集
bash
Copy Code
localedef --force --inputfile=zh_CN --charmap=UTF-8 zh_CN.UTF-8 # 覆盖现有字符集文件
验证字符集完整性
bash
Copy Code
locale -a | grep "zh_CN.utf8" # 应输出 "zh_CN.utf8",无警告信息
三、检查环境变量持久化配置
确保/etc/locale.conf配置正确
bash
Copy Code
cat /etc/locale.conf # 需包含以下内容:
LANG=zh_CN.UTF-8
LC_ALL=zh_CN.UTF-8
若缺失,执行:
bash
Copy Code
echo -e "LANG=zh_CN.UTF-8\nLC_ALL=zh_CN.UTF-8" > /etc/locale.conf
刷新环境变量
bash
Copy Code
source /etc/locale.conf && export LC_ALL=zh_CN.UTF-8
四、终端编码与SSH客户端设置验证
临时测试中文显示
bash
Copy Code
echo "中文测试" # 若终端输出乱码,检查SSH客户端编码(需设为 UTF-8)
重启服务或终端
部分终端工具需重启会话才能应用编码设置,建议断开重连后再次测试。
关键说明
重复包的影响:glibc-common包含locale配置文件,多版本共存可能导致字符集文件路径混乱,卸载旧版本可消除潜在冲突
2
4。
字符集强制生成:localedef --force可修复因文件损坏或权限问题导致的字符集失效,确保zh_CN.UTF-8被正确识别
4。
完成以上步骤后,中文乱码问题通常可解决。若仍存在异常,可进一步检查/etc/profile.d目录下是否有覆盖LANG变量的脚本(如lang.sh),并注释冲突配置。
查看5篇参考资料
Linux系统案例精解 存储、Oracle数据库、集群、性能优化、系统管理、网络配置 rpm 安装 软件
fake-book.baidu-int.com
RPM软件包管理工具使用指南
阿里云开发者社区
Linux下查看软件安装与安装路径
阿里云开发者社区
docker 容器中设置中文语言包的问题
CSDN博客
深入解析GNU C库(glibc)核心功能与实战应用
CSDN博客
存在异常,如何可进一步检查/etc/profile.d目录下是否有覆盖LANG变量的脚本(如lang.sh),并注释冲突配置。
进一步检查并处理/etc/profile.d目录下覆盖LANG变量的脚本
1. 查找覆盖LANG变量的脚本
执行以下命令,遍历/etc/profile.d目录下所有.sh脚本,筛选包含LANG或LC_ALL的文件:
bash
Copy Code
grep -rni "LANG\|LC_ALL" /etc/profile.d/*.sh
重点关注输出中包含export LANG=或LANG=的行,这些可能是覆盖语言变量的配置(如历史对话中提到的lang.sh强制重置中文为英文的逻辑)。
2. 定位冲突配置并注释
若找到目标脚本(如/etc/profile.d/lang.sh),使用文本编辑器打开:
bash
Copy Code
vi /etc/profile.d/lang.sh
搜索包含zh*或强制设置LANG=en_US.UTF-8的行(例如:zh*) LANG=en_US.UTF-8 ;;),在行首添加#注释冲突配置:
bash
Copy Code
# zh*) LANG=en_US.UTF-8 ;; # 注释此行以取消强制重置
保存退出后,执行source /etc/profile.d/lang.sh使修改生效。
3. 验证环境变量是否生效
通过以下命令确认LANG变量未被覆盖:
bash
Copy Code
echo $LANG # 应输出zh_CN.UTF-8(若已配置)
locale # 检查LC_ALL等变量是否与LANG一致
4. 处理其他潜在冲突
若存在多个脚本设置LANG(如/etc/profile.d/zh_CN.sh与lang.sh冲突),可通过以下方式优先级排序:
文件名排序:/etc/profile.d目录下的脚本按字母顺序执行,后执行的脚本会覆盖先执行的配置,可重命名冲突脚本(如zz-zh_CN.sh确保最后执行)。
权限检查:确保目标脚本有可执行权限(chmod +x /etc/profile.d/zh_CN.sh),否则可能被系统忽略
5。
完成以上步骤后,重启终端或重新登录,即可避免LANG变量被强制重置,恢复中文显示。
posted on 2025-12-21 20:22 sunny_2016 阅读(2) 评论(0) 收藏 举报
浙公网安备 33010602011771号