[Linux] 環境變數 LANG, LC_*, LC_ALL 對 L10N gettext 的影響

[Linux] 環境變數 LANG, LC_*, LC_ALL 對 L10N gettext 的影響

今天在 Linux 上查看一個 MO 檔裡的字串時,

遇到了一個奇怪的問題…

 

我用下面的指令,指定環境變數 LANG 為 ja_JP,

再用 gettext 來取得 /l10n/ja_JP/LC_MESSAGES/test.mo 裡面的 “Hello” 這個字串:

LANG=ja_JP python -c 'import gettext; gettext.bindtextdomain("test", "/l10n"); print gettext.dgettext("test", "Hello")'

 

LANG 是 en_US (英文) 的話,取得的就是 “Hello”。

LANG 是 ja_JP (日文) 的話,取得就是 “Hello” 翻譯成日文後的 “こんにちは”。

平常這麼做都沒有問題,

今天卻是 LANG 設成 ja_JP 後,取到的還是英文的 “Hello”,

是怎麼回事呢?

 

研究了半天,原來是被 LANG, LC_*, 和 LC_ALL 這些環境變數影響了~

這幾個環境變數都會影響 L10N 的結果,

以優先權來說,是 LC_ALL > LC_* > LANG

因為機器上已經先設定了一個 LC_ALL=C 的環境變數,

因此就算我指定 LANG 也是沒有用的…

 

用 locale 指令可以看到這些環境變數的影響~

假設目前 LC_ALL, LC_*, LANG 等變數都沒有設定,

那預設 LC_* 會使用 POSIX:

testuser@localhost ~ $ locale

LANG=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

 

當我設定了 LANG 之後,LC_* 就會使用 LANG 的值:

testuser@localhost ~ $ LANG=C locale

LANG=C
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=

 

當 LC_CTYPE 也設定時,

除了 LC_CTYPE 以外的 LC_* 會維持使用 LANG 的值:

testuser@localhost ~ $ LANG=C LC_CTYPE=en_US.UTF8 locale

LANG=C
LC_CTYPE=en_US.UTF8
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=

 

最後,當效力最強的 LC_ALL 被設定時,

所有的 LC_* 都會被設定成和 LC_ALL 相同的值:

testuser@localhost ~ $ LANG=C LC_CTYPE=en_US.UTF8 LC_ALL=ja_JP.UTF-8 locale

LANG=C
LC_CTYPE="ja_JP.UTF-8"
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_PAPER="ja_JP.UTF-8"
LC_NAME="ja_JP.UTF-8"
LC_ADDRESS="ja_JP.UTF-8"
LC_TELEPHONE="ja_JP.UTF-8"
LC_MEASUREMENT="ja_JP.UTF-8"
LC_IDENTIFICATION="ja_JP.UTF-8"
LC_ALL=ja_JP.UTF-8

 

因此,最上面的例子要成功在所有狀態下,

都能取得日文字串的話,應該要使用 LC_ALL 而不是 LANG:

LC_ALL=ja_JP python -c 'import gettext; gettext.bindtextdomain("test", "/l10n"); print gettext.dgettext("test", "Hello")'

 

參考資料:Linux的locale、LC_ALL和LANG – LC_coding – 博客园

(本頁面已被瀏覽過 1,039 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料