Liu*_* 刘研 12 linux filesystems character-encoding filenames
由于Windows(GBK编码)和Linux(UTF-8编码)之间有大量的文件交换工作,所以很容易遇到字符编码问题,例如:
前面提到的常见问题是文件定位/命名。谷歌搜索后,我得到了一篇文章Using Unicode in Linux https://www.linux.com/news/using-unicode-linux/,它说:
操作系统和许多实用程序没有意识到文件名中的字节代表什么字符。
因此,可能有两个具有相同名称的文件(当它们的名称由正确的字符集解码时为SAME,但以字节为单位不同),例如??.txt,但采用不同的编码:
[root@fedora test]# ls
???? ??
[root@fedora test]# ls | iconv -f GBK
??
?iconv: illegal input sequence at position 7
[root@fedora test]# ls ?? && ls $'\xd6\xd0\xce\xc4' | iconv -f gbk
??
??
Run Code Online (Sandbox Code Playgroud)
问题:
$'\xe4\xb8\xad\xe6\x96\x87.txt'zh_CN.UTF-8 环境中的文件名 ??.txt ( $'\xd6\xd0\xce\xc4.txt') 和 zh_CN.GBK 环境中的文件名 ??.txt ( )引用同一个文件?我对您的问题进行了一些重新表述,原因在您按顺序阅读时应该很明显。
不,这是不可能的:正如您在问题中提到的,UNIX 文件名只是一个字节序列;内核对编码一无所知,这完全是一个用户空间(即应用程序级)概念。
换句话说,内核对LANG/一无所知LC_*,因此无法进行翻译。
您可以有多个目录条目引用同一个文件;你可以通过硬链接或符号链接来实现。
但是请注意,在当前编码中无效的文件名(例如,当您在 UTF-8 语言环境中工作时的 GBK 字符串)会显示得很糟糕,如果有的话。
您无法修补内核来执行此操作(请参阅 1.),但理论上您可以修补 C 库(例如 glibc)以执行此转换,并在调用内核时始终将文件名转换为 UTF-8,并在从内核读取文件名时将它们转换回当前编码。
一种更简单的方法是使用FUSE编写覆盖文件系统,它只是在将文件名转换为 UTF-8 或从 UTF-8 转换后将任何文件系统请求重定向到另一个位置。理想情况下,您可以将这个文件系统挂载到 中~/trans,当访问时
~/trans/a/GBK/encoded/path,FUSE 文件系统真正访问
/a/UTF-8/encoded/path。
但是,这些方法的问题在于:您如何处理文件系统中已存在且未采用 UTF-8 编码的文件?你不能只是简单地将它们未经翻译地传递,因为那样你就不知道如何转换它们;您不能通过将无效字符序列转换为来破坏它们,?因为这可能会造成冲突......