CentOS7 pure-ftpd上传中文文件名乱码解决
把网站搬家到CentOS7后,pure-ftpd明明跑得快,却总在中文文件名上翻车:传上去变成“????.jpg”,下载回来又变“�.png”,用户骂,老板催,运维头秃。别急着换软件,九成乱码都是系统locale和pure-ftpd编码没对齐,三分钟就能摁死。

为什么pure-ftpd在CentOS7下总让中文文件名翻车
pure-ftpd默认用UTF-8跟客户端握手,可CentOS7最小装完locale常常是C或POSIX,系统层面不认识UTF-8,文件名一进硬盘就被当成字节流,再被vsftpd或nginx一读,直接散架。上传“海报.png”,目录里只剩“????.png”,本质就是系统、ftp服务、shell三方编码各唱各的调。
先查系统locale,别让基础掉链子
登录服务器,执行locale,如果输出里一行UTF-8都没有,先打补丁:
localectl set-locale LANG=zh_CN.UTF-8
立即生效:source /etc/locale.conf,再跑locale确认每行都带UTF-8。这一步不做,后面全白搭。

pure-ftpd编译参数里藏着的编码开关
很多人用yum直接装epel版,没注意编译参数。自己编译时,一定加上:
./configure --with-language=simplified-chinese --with-unicode
epel版如果没这俩参数,上传中文依旧炸,那就换源码编译,别怕麻烦。
配置文件三行代码,强制UTF-8
编辑/etc/pure-ftpd/pure-ftpd.conf,找到下面三处,改成这样:

UTF8 yes
ClientCharset UTF-8
FileSystemCharset UTF-8
保存后systemctl restart pure-ftpd,重启是生效关键,reload没用。
客户端也别甩锅,FileZilla要勾强制UTF-8
FileZilla默认“自动检测”,可老版本检测失败就退回ISO-8859-1,中文秒变乱码。打开站点管理器,字符集选“强制UTF-8”,再连接,目录瞬间 readable。
如果系统里已有乱码文件,如何批量救回
先别rm,用convmv抢救:
yum install convmv -y
convmv -f gbk -t utf8 -r --notest /var/www/html/upload/
这条命令把目录内所有GBK文件名递归转成UTF-8,--notest是真干活,不加就白跑。
防火墙与SELinux别背锅
有人改完依旧问号,其实是SELinux把ftp进程拦了。快速排雷:
getsebool -a | grep ftp
看到ftphomedir、allowftpdfull_access是off就打开:
setsebool -P ftphomedir 1
setsebool -P allowftpdfull_access 1
SELinux不点头,pure-ftpd就算UTF-8全开也写不进目录。
一键检查脚本,上传前自测
把下面脚本存成test-utf8.sh,跑完就知道环境行不行:
#!/bin/bashecho "系统locale:"; locale | grep UTF8
echo "pure-ftpd是否UTF8:"; grep -i utf8 /etc/pure-ftpd/pure-ftpd.conf
echo "SELinux ftp权限:"; getsebool -a | grep ftp | grep -v off
echo "临时创建中文文件测试:"; touch /tmp/中文测试.txt; ls /tmp/中文*
如果每一行都绿色,再传文件稳如老狗。
常见坑汇总,别再踩第二遍
1. 只改客户端字符集,不改服务器,双端对不上依旧炸。
2. 用Windows自带资源管理器连接,系统代码页是GBK,传完就乱,换用FileZilla或WinSCP。
3. 把locale写到~/.bashrc里,以为永久生效,结果pure-ftpd是systemd启动,读不到用户变量,必须写/etc/locale.conf。
4. 忘了重启服务,配置再对也白给。
总结步骤,按顺序执行一次过
1. localectl设UTF-8 → 2. 源码编译带unicode → 3. 配置文件三行UTF8 → 4. 客户端强制UTF-8 → 5. convmv救回老文件 → 6. SELinux放行。六步走完,CentOS7 pure-ftpd中文文件名乱码彻底消失,再传“活动海报2024 final版.png”也稳。
