Linux文件名乱码源于编码错位,本质是Windows的GBK与Linux的UTF-8不匹配;convmv专用于批量转换文件名编码,支持预览与递归处理,而file、iconv等仅适用于文件内容。
Linux 本身不记录文件名的编码识别历史——文件名在内核层面只是字节序列,没有元数据标记其编码。所谓“查看文件名编码识别记录”,实际是误读了概念;你真正需要的是「如何判断当前目录下中文文件名用的是什么编码」以及「为什么 ls 显示乱码」。
ls 显示中文文件名是问号或方块这不是文件名“被识别错了”,而是终端环境(LANG、LC_CTYPE)与文件名原始字节解释方式不匹配。比如:
GBK 字节,但你的终端 LANG=en_US.UTF-8,就会把每个 GBK 双字节当两个非法 UTF-8 序列,显示为 ??
ls 本身不做编码转换,它只是把目录项字节原样传给终端;终端按自己的 locale 解码失败,就 fallback 成 或空格getfattr、stat 都查不到这类信息核心思路:用不同编码解释同一组字节,看哪一种能还原出可读的中文。常用组合只有两种——UTF-8 和 GBK(即 CP936),其他如 BIG5 在简体中文场景极少出现。
locale 看 LC_CTYPE 值,比如 zh_CN.UTF-8 表示终端期望 UTF-8 文件名convmv 尝试反向解码:convmv -f utf-8 -t gb2312 --notest *(不加 --notest 先预览),如果输出里出现合理中文名,说明原始文件名很可能是 GBK 编码convmv 是唯一靠谱的文件名编码诊断工具file、enca、iconv 全部作用于文件内容,对文件名完全无效。convmv 是专为文件名设计的工具,它不修改内容,只重解释和重命名字节序列。
sudo apt install convmv(Debian/Ubuntu)或 sudo yum install convmv(RHEL/CentOS)convmv -f gb2312 -t utf-8 --notest *.txt
convmv -f gb2312 -t utf-8 --notest *.txt,注意它默认跳过已含 UTF-8 字节的文件名convmv 不支持自动探测,必须手动指定 -f;它也没有“记录”功能,每次都是实时计算真正容易被忽略的点:文件名编码问题从来不是孤立的,它必然伴随挂载选项(如 mount -o iocharset=utf8 对 vfat)、Samba 配置(unix charset = GBK)、或 NFS 字符集协商失败。只盯着单个文件名查编码,往往绕远路。