[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 次)