如果你是一個Linux新手,並且剛剛安裝了一個新的英文系統但想要設置成中文系統,肯定會接觸到上面幾個變量,在網上搜索了一系列解決方法,給一些變量賦一下值,再export一下,或者寫到配置文件裡面,然後就搞定了,但究竟為什麼要這樣做,可能還是一知半解。通過這兩天自己對網上看到的一些文章的整理和自己的試驗,在這裡記錄一下自己的理解。
一、什麼是locale
locale這個單詞中文翻譯成地區或者地域,其實這個單詞包含的意義要寬泛很多。Locale是根據計算機用戶所使用的語言,所在國家或者地區,以及當地的文化傳統所定義的一個軟件運行時的語言環境。
上面這個解釋摘上網上,說得好玄乎,舉兩個簡單的例子:
a)在“簡體中文”的環境,運行df命令,第一行顯示的是:
文件系統 1K-塊 已用 可用 已用% 掛載點
而在“繁體中文”的環境下,運行df命令,第一行顯示的是:
檔案系統 1K-區段 已用 可用 已用% 掛載點
b)在中文環境下運行date命令,顯示的是
2013年 01月 27日 星期日 15:57:01 CST
而在英文環境下,運行date命令,顯示的是
Sun Jan 27 15:57:46 CST 2013
看到上面兩個例子,我想應該比較清楚了,不同地區對一些計算機詞匯、日期顯示等方面都有各自的習慣,比如中國大陸通常使用“文件系統”,而台灣或者香港地區則會用“檔案系統”,這顯然不是簡單的從簡體到繁體的轉換而已,所以可以想像,有一套系統在為各個地區的本地化服務。
locale把按照所涉及到的使用習慣的各個方面分成12個大類,這12個大類分別是:
1、語言符號及其分類(LC_CTYPE)
2、數字(LC_NUMERIC)
3、比較和習慣(LC_COLLATE)
4、時間顯示格式(LC_TIME)
5、貨幣單位(LC_MONETARY)
6、信息主要是提示信息,錯誤信息,狀態信息,標題,標簽,按鈕和菜單等(LC_MESSAGES)
7、姓名書寫方式(LC_NAME)
8、地址書寫方式(LC_ADDRESS)
9、電話號碼書寫方式(LC_TELEPHONE)
10、度量衡表達方式 (LC_MEASUREMENT)
11、默認紙張尺寸大小(LC_PAPER)
12、對locale自身包含信息的概述(LC_IDENTIFICATION)。
而這些信息的配置通常放在/usr/share/i18n/locales目錄下,讓我們打開一下zh_CN和en_US,看看裡面都定義了一些什麼東西和有一些什麼區別,對比一個比較簡單的,LC_TIME有這樣的定義
zh_CN:
day "<U661F><U671F><U65E5>";/
"<U661F><U671F><U4E00>";/
"<U661F><U671F><U4E8C>";/
"<U661F><U671F><U4E09>";/
"<U661F><U671F><U56DB>";/
"<U661F><U671F><U4E94>";/
"<U661F><U671F><U516D>"
mon "<U4E00><U6708>";"<U4E8C><U6708>";"<U4E09><U6708>";/
"<U56DB><U6708>";"<U4E94><U6708>";"<U516D><U6708>";/
"<U4E03><U6708>";"<U516B><U6708>";"<U4E5D><U6708>";/
"<U5341><U6708>";"<U5341><U4E00><U6708>";"<U5341><U4E8C><U6708>"
en_US:
day "<U0053><U0075><U006E><U0064><U0061><U0079>";/
"<U004D><U006F><U006E><U0064><U0061><U0079>";/
"<U0054><U0075><U0065><U0073><U0064><U0061><U0079>";/
"<U0057><U0065><U0064><U006E><U0065><U0073><U0064><U0061><U0079>";/
"<U0054><U0068><U0075><U0072><U0073><U0064><U0061><U0079>";/
"<U0046><U0072><U0069><U0064><U0061><U0079>";/
"<U0053><U0061><U0074><U0075><U0072><U0064><U0061><U0079>"
mon "<U004A><U0061><U006E><U0075><U0061><U0072><U0079>";/
"<U0046><U0065><U0062><U0072><U0075><U0061><U0072><U0079>";/
"<U004D><U0061><U0072><U0063><U0068>";/
"<U0041><U0070><U0072><U0069><U006C>";/
"<U004D><U0061><U0079>";/
"<U004A><U0075><U006E><U0065>";/
"<U004A><U0075><U006C><U0079>";/
"<U0041><U0075><U0067><U0075><U0073><U0074>";/
"<U0053><U0065><U0070><U0074><U0065><U006D><U0062><U0065><U0072>";/
"<U004F><U0063><U0074><U006F><U0062><U0065><U0072>";/
"<U004E><U006F><U0076><U0065><U006D><U0062><U0065><U0072>";/
"<U0044><U0065><U0063><U0065><U006D><U0062><U0065><U0072>"
有人就要問了,<UXXXX>是什麼東西,這是Unicode編碼的值。這麼一說,應該很多人馬上就看出來了,上面的“day”就是對“星期”定義,而“mon”就是對“月份”的定義。
所以上面其實是
zh_CN:
day 星期日;
星期一;
...
mon 一月;二月;...
en_US:
day Sunday;
Monday;
...
mon January;
February;
...
是的,這就是為什麼date命令能夠根據不同地區而顯示不同內容的原因,都是通過本地化系統配置完成的。
二、如何配置locale
通過locale命令,可以看到LC_*各個變量的設置,如下:
[user~]$ locale
LANG=zh_CN.UTF-8
LC_CTYPE="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_PAPER="zh_CN.UTF-8"
LC_NAME="zh_CN.UTF-8"
LC_ADDRESS="zh_CN.UTF-8"
LC_TELEPHONE="zh_CN.UTF-8"
LC_MEASUREMENT="zh_CN.UTF-8"
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_ALL=
運行date命令,我們可以看到
[user~]$date
2013年 01月 27日 星期日 17:01:46 CST
下面我們設置LC_TIME變量
[user~]$LC_TIME=en_US.utf8;date
2013年 01月 27日 星期日 17:04:03 CST
咦,怎麼還是中文的?是的,不是BUG,你還要將LC_TIME變量export一下,這涉及進程間環境變量的設置問題,這裡不多述:
[user~]$ export LC_TIME;date
Sun Jan 27 17:04:33 CST 2013
我們可以看到,將LC_TIME變量設置成en_US之後,date命令的日期的顯示改變了
可是我們如果運行ls -al命令的話,卻看到
[user~]$ ls -al
總計 0
drwx------ 10 user users 4096 2013-01-01 16:47 .
drwx------ 10 user users 4096 2013-01-01 14:51 ..
這裡日期並沒有以英文的顯示習慣“Jan 1 16:47”顯示,這並不奇怪,因為ls命令很可能使用不是LC_TIME變量。
而如果我們設置LC_MESSAGES變量
[user~]$ LC_MESSAGES=en_US.utf8;export LC_MESSAGES;ls -al
total 0
drwx------ 10 user users 4096 2013-01-01 16:47 .
drwx------ 10 user users 4096 2013-01-01 14:51 ..
可以看到,“總計 0” 變成 “total 0” 了。
三、LC_ALL、LANG和LC_*的關系
設定locale就是設定12大類的locale分類屬性,即 12個LC_*。除了這12個變量可以設定以外,為了簡便起見,還有兩個變量: LC_ALL和LANG。它們之間有一個優先級的關系: LC_ALL>LC_*>LANG 可以這麼說,LC_ALL是最上級設定或者強制設定,而LANG是默認設定值。
重新打開一個窗口,使得LC_ALL、LANG和LC_*都回到原來的狀態,看一下各個變量的默認值。
[user~]$ echo $LANG
zh_CN.utf8
[user~]$ echo $LC_ALL
[user~]$ echo $LC_TIME
可以看到,除了LANG變量是zh_CN.utf8之外,其他的LC_*,包括LC_ALL都是空。可是,我們運行locale命令,卻看到
[user~]$ locale
LANG=zh_CN.UTF-8
LC_CTYPE="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
......
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_ALL=
每個值LC_*值都和LANG的值一樣,我們改變一下LANG的值再看一下情況
[user~]$ LANG=en_US.utf8;locale
LANG=en_US.utf8
LC_CTYPE="en_US.utf8"
LC_NUMERIC="en_US.utf8"
......
LC_IDENTIFICATION="en_US.utf8"
LC_ALL=
可以看到LC_*的值隨著默認值LANG的變化而變化。而此時,運行date
[user~]$date
Sun Jan 27 17:34:40 CST 2013
再設置LC_ALL的值,看一下結果
[user~]$ LC_ALL=zh_CN.utf8;export LC_ALL;date
2013年 01月 27日 星期日 17:36:24 CST
可以看到,設置LC_ALL屬性之後,原來的en_US.utf8屬性已經被重置了,此時再看一下locale命令
[user~]$ locale
LANG=en_US.utf8
LC_CTYPE="zh_CN.utf8"
LC_NUMERIC="zh_CN.utf8"
......
LC_IDENTIFICATION="zh_CN.utf8"
LC_ALL=zh_CN.utf8
從上面的試驗可以看到,LANG是LC_*的默認值,LC_*變量可以單獨設置而可以與LANG不同。而LC_ALL比LC_*的優先級別高,設置完LC_ALL之後,會強制重置LC_*各個值,如果不將LC_ALL重新設置為空,則再無法設置LC_*的單個值 。
That‘s all~上面就是這兩天所得的一些總結,希望對大家有幫助。如果有解釋得不對的,歡迎拍磚~
轉自:http://www.niba.com/f/1314803a_6771608.html
作者:戀上呼吸的樣子
http://xxxxxx/Linuxjc/1181648.html TechArticle