歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 淺析 Linux 的國際化與本地化機制

淺析 Linux 的國際化與本地化機制

日期:2017/2/28 16:40:30   编辑:Linux教程

什麼是國際化和本地化

不同的國家和地區因文化的差異,在日期、時間以及貨幣符號等表示方式上都不完全相同,最為明顯的就是語言。有時在編寫軟件給用戶使用時,開發者、維護者以及最終用戶可能分別來自不同的區域,而要求他們均使用同一種語言顯然是不明知的,因此當一個程序或者軟件編寫給全世界人使用時,通常分為兩個部分:國際化 (internationalization,即縮寫為 i18n,這是由於在這個單詞的頭尾之間包含了 18 個字母 ) 和本地化 (localization,縮寫為 l10n)。

NLS

NLS 即是 Native Language Support。Linux 為解決各文件系統文件名多語言的問題而引入了對 NLS 的支持,我們可在內核編譯配置中找到相關選項。

國際化,指的是一個程序或軟件可給特定的人群使用而無須修改或重新編譯源代碼。在 ISO C 中,國際化的工作依賴於 locales。程序開發者可使用多樣的方式來國際化他們的程序,但是 GNU gettext 已成為了其中的一種標准。

本地化,指的是一個程序或軟件在支持國際化的基礎上,給定程序特定區域的語言信息使其在信息的輸入輸出等處理上適應特定區域人群的使用。這裡允許程序所使用的一些語言環境變量在程序執行時動態配置。

簡單的說,國際化是開發者的任務,是一個一般化的過程,而本地化則是翻譯者所做的事情,是一個具體的過程。國際化的運作為本地化工作提供了可能。對於國際化和本地化,有時我們也稱為 NLS。Glibc (GNU C library) 作為 Linux 的 C 標准庫為 Linux 處理國際化與本地化提供了基礎,如圖 1 所示 Linux 上的程序處理依賴於 glibc。

圖 1. glibc 在 linux 上的基礎作用

使用和設定系統 locale

對用戶而言,用來控制語言或區域環境生效的功能就叫做 locale。locale 是 glibc 的一個重要組成部分,也是 Linux 國際化和本地化工作的一個重要基礎。locale 通過設置一系列的環境變量來滿足用戶對國際化和本地化的需求。通過 locale 命令,我們不僅可查看到語言環境的當前設置,還可查看當前 locale 可用的名稱和字符集。

清單 1. 系統當前 locale 環境變量值

$ locale

LANG=en_US.UTF-8 # 未設置任何 LC_xxx 變量時所使用的默認值

LC_CTYPE=zh_CN.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" # 對 locale 自身信息的概述

LC_ALL= # 用來覆蓋掉所有其他 LC_xxx 變量的值

除 清單 1 中所示的,另有用於指定 locale 可用名稱目錄的變量 LOCPATH,默認使用的路徑是 /usr/lib/locale/。另外,當一個程序找尋 locale 環境變量值時,它會依以下優先順序使用變量。

清單 2. locale 相關變量使用時的優先順序

[1] LANGUAGE

[2] LC_ALL

[3] LC_xxx

[4] LANGGER

其中 LC_ALL 並不是一個環境變量,它僅是一個可被函數 setlocale (setlocale 的函數原型及其參數 category 的可用值均被定義在頭文件 locale.h 中 ) 調用的宏,它的值可覆蓋所有其他的 locale 設定 ( 如果 LC_ALL 的值存在的話,即非空 ) 。LANG 用於正常指定使用某區域環境值,而 LANGUAGE 則用於指定個人對語言環境值的主次偏好。通常我們會在設定 LANG 後,並通過 LC_xxx 加以修正。

LANGUAGE="en_US:en"

LANG="en_US.UTF-8"

LC_CTYPE="zh_CN.UTF-8"

您可將以上內容添加至 /etc/profile 或 /etc/environment 等系統初始文件中,以保證系統在啟動後立即使用您所期望的語言環境。值得注意的是,若 locale 被設定為 "C",那麼 LANGUAGE 的值將被忽視。因此我們必須為 LANG ( 或 LC_ALL) 設置有效的 locale 名稱,而非 "C"。

清單 3. 當前系統可用的 locale 名稱

$ locale – a

C

en_AU.utf8

...

POSIX

zh_CN.utf8

...

在 清單 3 中我們看到了兩個特別的 locale 名稱,C 和 POSIX。當前,POSIX 僅是 C 的一個別名。除 C 和 POSIX 之外,locale 的名稱並未標准化。同時,清單 3 中可用名稱的輸出已依 LC_COLLATE 所指定的排序規則進行了排序。另外,我們看到 locale 的名稱存在一個命名的格式。

language[_territory[.codeset]][@modifier]

其中 language 是 ISO 639-1 標准中定義的語言代碼,territory 是 ISO 3166-1 標准中定義的國家和地區代碼,codeset 是字符集的名稱 ( 如 UTF-8 等 ),而 modifier 則是某些 locale 變體的修正符。若期望使用的 locale 名稱未在以上的列表中,那麼我們可使用 glibc 提供的命令 localedef 進行添加 ( 見 清單 4,命令 localedef 會在相關路徑生成必要的數據文件 )。

清單 4. 通過命令 localedef 添加 fi_FI.UTF-8

[1] localedef -f UTF-8 -i fi_FI fi_FI.UTF-8

[2] localedef -f UTF-8 -i fi_FI ./fi_FI

方式 1 將在默認路徑上生成一個 locale-archive 文件,而方式 2 則在指定路徑產生一個目錄,該目錄中將包含 locale 相關的數據。另外,命令 localedef 還提供了 --no-archive 選項,該選項可使方式 1 生成的也是一個目錄,而非 locale-archive 文件。下面我們通過設置 LC_ALL 和 LC_TIME 的值來了解該 locale 環境變量對時間和日期格式的影響,從而更好的理解 locale 環境變量在系統上的基礎作用 ( 見 清單 5,另外我們需在運行前確定該 locale 名稱是有效的 )。

清單 5. locale 環境變量對系統命令的影響

$ LC_ALL=en_US.UTF-8 date

Thu Nov 5 14:13:36 CST 2009

$ LC_TIME=fi_FI.UTF-8 date

to 5.11.2009 14.13.44 +0800

$ LC_ALL=zh_CN.UTF-8 locale -ck LC_TIME

LC_TIME

abday="日 ; 一 ; 二 ; 三 ; 四 ; 五 ; 六"

...

...

date_fmt="%Y 年 %m 月 %d 日 %A %H:%M:%S %Z"

time-codeset="UTF-8"

在這裡另要指出的是,由 GNU coreutils 提供的 date 命令在實現時加入了以下內容,而這正是 date 命令實現國際化和本地化的關鍵 ( 見清單 6)。

清單 6. date 命令的源碼片斷

setlocale (LC_ALL, "");

bindtextdomain (PACKAGE, LOCALEDIR);

textdomain (PACKAGE);

Copyright © Linux教程網 All Rights Reserved