Linux

關於linux上文件系統字元編碼的幾個問題

  • October 12, 2020

由於 Windows(GBK編碼)和 Linux(UTF-8編碼)之間有很多文件交換工作,很容易遇到字元編碼問題,例如:

  • 在 Windows 系統上壓縮/tar 文件名中包含漢字,在 Linux 系統上解壓/解壓。
  • 執行遷移的遺留 Java Web 應用程序(在 Windows 系統上設計,在 JSP 中使用 GBK 編碼),它將 GBK 編碼命名的文件寫入磁碟。
  • ftp 在 Windows FTP 伺服器和 Linux 客戶端之間獲取/放置以 GBK 編碼命名的文件。
  • 在 Linux 中切換 LANG 環境。

前面提到的常見問題是文件定位/命名。Google搜尋後,我得到了一篇文章Using Unicode in Linux https://www.linux.com/news/using-unicode-linux/,它說:

作業系統和許多實用程序沒有意識到文件名中的字節代表什麼字元。

因此,可能有兩個具有相同名稱的文件(它們的名稱由正確的字元集解碼時相同,但以字節為單位不同),例如中文.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
中文
中文

問題:

  1. 是否可以配置 linux 文件系統使用固定字元編碼(如NTFS在內部使用 UTF-16)來儲存文件名,而不管 LANG/LC_ALL 環境如何?
  2. 或者,我真正想問的是:是否可以讓$'\xe4\xb8\xad\xe6\x96\x87.txt'zh_CN.UTF-8環境下的文件名中文.txt( $'\xd6\xd0\xce\xc4.txt')和zh_CN.GBK環境下的文件名中文.txt()引用同一個文件
  3. 如果它不可配置,那麼是否可以修補核心以在文件系統和目前環境之間轉換字元編碼(只是一個問題,而不是請求實現)?如果可能的話,有多少性能影響?

我對您的問題進行了一些重新表述,原因在您按順序閱讀時應該會很明顯。

1. 無論 LANG/LC_ALL 環境如何,是否可以配置 linux 文件系統使用固定字元編碼來儲存文件名?

不,這是不可能的:正如您在問題中提到的,UNIX 文件名只是一個字節序列;核心對編碼一無所知,這完全是一個使用者空間(即應用程序級)的概念。

換句話說,核心對LANG/一無所知LC_*,因此它無法翻譯。

2. 可以讓不同的文件名引用同一個文件嗎?

您可以有多個目錄條目引用同一個文件;您可以通過硬連結符號連結來實現。

但是請注意,在目前編碼中無效的文件名(例如,當您在 UTF-8 語言環境中工作時,您的 GBK 字元串)將顯示很差,如果有的話。

3. 是否可以修補核心以在文件系統和目前環境之間轉換字元編碼?

您無法修補核心來執行此操作(請參閱 1.),但您可以 - 理論上 - 修補 C 庫(例如 glibc)以執行此轉換,並在呼叫核心時始終將文件名轉換為 UTF-8,並在從核心讀取文件名時將它們轉換回目前編碼。

一種更簡單的方法可能是使用FUSE編寫一個覆蓋文件系統,它只是在將文件名轉換為/從 UTF-8 之後將任何文件系統請求重定向到另一個位置。理想情況下,您可以掛載這個文件系統~/trans,當訪問時 ~/trans/a/GBK/encoded/path,FUSE 文件系統真正訪問 /a/UTF-8/encoded/path

但是,這些方法的問題是:您如何處理文件系統上已經存在且不是 UTF-8 編碼的文件?您不能只是簡單地將它們傳遞給未翻譯,因為那樣您就不知道如何轉換它們;您不能通過將無效字元序列轉換為來破壞它們,?因為這可能會產生衝突……

引用自:https://unix.stackexchange.com/questions/15419