Locale

為什麼語言環境中包含字元集?

  • February 18, 2017

據我了解,POSIX 表示語言環境定義必須包含一種字元編碼類型,如 UTF-8。語言環境通常作為 shell 環境變數實現。

為什麼這兩個概念不分開?例如,現在我們有多個 en_US 語言環境,具體取決於支持的編碼數量。從設計的角度來看,這似乎很混亂且難以擴展,那麼其基本原理是什麼?

有些語言,比如中文,可以用多個字元集編寫,而且都是正確的。它們有一個更新的、簡化的字元集,也有一個更複雜的傳統字元集。或者蒙古語或塞爾維亞語都可以用西里爾文或拉丁文書寫。

此外,許多語言的重音字元(如 ä、ö 和類似字元)在不同的編碼中具有不同的程式碼,儘管它們在螢幕上是相同的。因此,將 ä 寫入文件,意味著如果該文件由 utf8 編碼,則您將不同的字節序列寫入該文件,就好像它是按照不同的標準編碼的(在我的範例中,它的名稱是 iso8859-1 編碼)。

此外,有些編碼可以支持一種或某些語言。例如,iso8859-1 支持大多數西歐語言,iso8859-2 支持中歐和東歐語言,直到它們用拉丁文字編寫。Ascii 僅支持英語,但 utf8 支持世界上幾乎所有的語言。

因此,語言與可能的編碼之間存在多對多的關係:語言可以通過多種編碼進行編碼,並且大多數編碼可以用於多種語言。

編碼兼容性也存在多對多關係:例如,iso8859-2 向上兼容 ascii,但 ebcdic 不兼容。

編碼兼容性之間也存在多對多的關係。例如,ebcdic 可以轉換為 ascii,但 iso8859-2 不能。

因此,存在部分兼容標準的複雜網路。實際使用的編碼完全屬於語言環境。因此,它必須與語言類似地處理。這就是為什麼使用相同的環境變數處理它的原因。

儘管有可能,並且在我看來,這是一種更好的方法,但如果它由不同的環境變數處理的話。因此,編碼作為語言會有不同的環境變數,它不會是語言字元串的擴展。其原因主要是歷史原因,出於兼容性原因。

但是,至少在 glibc 中,也支持不同的環境變數。這就是我的一個英語 linux 上的“語言環境”輸出的樣子:

$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

如您所見,有不同的 LANG 和 LANGUAGE 環境變數。不幸的是,這主要是為了一些標準的兼容性,系統看起來並沒有真正遵循它。

延期:

關於歷史:在古代,幾乎所有的系統都是美式英語,採用ASCII或EBCDIC編碼。多語言或多編碼支持是聞所未聞的,如果它們被開發出來,它們會使用臨時解決方案(例如,通過覆蓋系統韌體中的字元集點陣圖)。我當時也在 1988 年左右開發了對 c64 的 latin2 字元支持(我只提供了 latin2 的一些字元,但沒有提供程式碼頁 - 當時我什至不知道什麼是程式碼頁)。程式碼頁是他們後來的發明,最初是為了標準化 ascii 的類似擴展。在大型機世界中使用了 ebcdic,它本質上與 ascii 不兼容,也發生了類似的轉換(ebcdic 最初是為了使穿孔卡片易於人類閱讀而開發的,

所有這些編碼都使用 1 個字元對應 1 個字節。在 Linux 中,多語言支持始於 libc4 時代(九十年代初)。Unicode 當時還不存在,它是一個新的、未實現的標準,所有的軟體都是在 1 char = 1 byte 的懷疑下開發的。為了使 utf 可行,所有這些都應該進行重大修改,這是接下來十年主要麻煩的根源。

所有語言擴展都使用字節的上半部分(ascii 僅指定 7 位,因此 ä、ö 或西里爾文/希臘文腳本的位置在 128-255 之間)。因此,這些也是彼此不相容的。因此,在當時,語言和程式碼頁之間的關係更像是一對一,就像現在的多對多一樣。

因此,支持一種語言也明確指定了要使用的程式碼頁。因此,不支持不同的程式碼頁,即使程式碼頁作為術語也不是很受歡迎。可想而知,當時win95從win31的ibm850切換到cp1251,造成了多少麻煩,而大多數工具甚至都不知道codepage的存在。

在 Linux 中,語言由 LANG 環境變數中的 2 個字元決定,僅此而已。語言方言支持(比如巴西葡萄牙語的“pt_BR”而不是簡單的“pt”)已經是一個獨立的擴展。

utf8 迫切需要支持具有多個結尾的相同語言。雖然這個問題當時已經存在(參見塞爾維亞語,什麼可以用西里爾字母和拉丁字母書寫),但它只對一些小語言造成了麻煩(據我所知,塞爾維亞人只是用拉丁字母寫一切)。因此,多編碼支持是持續不斷發展的下一步。因此,它遵循了共同的模式:語言字元串的進一步擴展。

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