linux系統字符編碼詳解

    衆所周知,地球上的語言多種多樣,在計算機世界,自然也是要適應各種語言.我們安裝各種系統的時候也是明示了要選擇語言環境和支持的語言環境.

    而linux系統的字符編碼設置尤爲複雜,這可能也是沒有考慮到非技術人員去研究這些東西吧.

    我遇到的事情是這樣的,我們使用了docker,但是docker容器裏的語言環境經常莫名錯亂,搞得很頭痛,所以偶爾就要切換,或者生成其他字符集.所以現在假設我們需要切換一箇中文語言環境,而切換了之後是亂碼的,也就是沒用的.

基本上,亂碼的原因就是沒加載到合適的字符編碼環境,即使是顯示到下面這樣的,其實也未必是加載到,只是證明這些變量更改成功而已.

#查看環境變量
vim /etc/profile
export LANG=zh_CN.UTF-8
export LANGUAGE=zh_CN.UTF-8
export LC_TIME=zh_CN.UTF-8
#加載一下
source /etc/profile
#看一下加載成功沒
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=

還要看看locale -a有沒有加載到系統上,

locale -a
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_COLLATE to default locale: No such file or directory
C
POSIX
en_US.utf8

大家看到了,系統上根本就沒有zh_CN.UTF-8的字符編碼,所以即使改了,也是沒有任何意義,所以你看到的還是會出現亂碼.


要解決這個問題,就要我們對linux字符編碼有比較透徹的理解.

首先,我們要看看我們的系統有哪些可支持的語言,都存在大名鼎鼎的i18n裏面,

#系統支持的語言環境
ll /usr/share/i18n/locales/
aa_DJ        ar_LY        ber_DZ      ca_FR       de_LU@euro  en_IN  es_EC       eu_ES       fur_IT          hi_IN               it_CH             kw_GB   ml_IN         nl_BE       POSIX             sid_ET       sv_FI@euro  translit_circle        tt_RU@iqtelif   yi_US
aa_ER        ar_MA        ber_MA      ca_IT       doi_IN      en_NG  es_ES       eu_ES@euro  fy_DE           hne_IN              it_IT             ky_KG   mni_IN        nl_BE@euro  ps_AF             si_LK        sv_SE       translit_cjk_compat    ug_CN           yo_NG
aa_ER@saaho  ar_OM        bg_BG       crh_UA      dv_MV       en_NZ  es_ES@euro  fa_IR       fy_NL           hr_HR               it_IT@euro        lb_LU   mn_MN         nl_NL       pt_BR             sk_SK        sw_KE       translit_cjk_variants  uk_UA           yue_HK
aa_ET        ar_QA        bho_IN      csb_PL      dz_BT       en_PH  es_GT       ff_SN       ga_IE           hsb_DE              iu_CA             lg_UG   mr_IN         nl_NL@euro  pt_PT             sl_SI        sw_TZ       translit_combining     unm_US          zh_CN
af_ZA        ar_SA        bn_BD       cs_CZ       el_CY       en_SG  es_HN       fi_FI       ga_IE@euro      ht_HT               iw_IL             li_BE   ms_MY         nn_NO       pt_PT@euro        so_DJ        szl_PL      translit_compat        ur_IN           zh_HK
am_ET        ar_SD        bn_IN       cv_RU       el_GR       en_US  es_MX       fi_FI@euro  gd_GB           hu_HU               ja_JP             lij_IT  mt_MT         nr_ZA       ro_RO             so_ET        ta_IN       translit_font          ur_PK           zh_SG
an_ES        ar_SY        bo_CN       cy_GB       el_GR@euro  en_ZA  es_NI       fil_PH      gez_ER          hy_AM               ka_GE             li_NL   my_MM         nso_ZA      ru_RU             so_KE        ta_LK       translit_fraction      uz_UZ           zh_TW
ar_AE        ar_TN        bo_IN       da_DK       en_AG       en_ZM  es_PA       fo_FO       gez_ER@abegede  i18n                kk_KZ             lo_LA   nan_TW@latin  oc_FR       ru_UA             so_SO        te_IN       translit_hangul        uz_UZ@cyrillic  zu_ZA
ar_BH        ar_YE        br_FR       de_AT       en_AU       en_ZW  es_PE       fr_BE       gez_ET          ia_FR               kl_GL             lt_LT   nb_NO         om_ET       rw_RW             sq_AL        tg_TJ       translit_narrow        ve_ZA
ar_DZ        as_IN        br_FR@euro  de_AT@euro  en_BW       es_AR  es_PR       fr_BE@euro  gez_ET@abegede  id_ID               km_KH             lv_LV   nds_DE        om_KE       sa_IN             sq_MK        th_TH       translit_neutral       vi_VN
ar_EG        ast_ES       brx_IN      de_BE       en_CA       es_BO  es_PY       fr_CA       gl_ES           ig_NG               kn_IN             mag_IN  nds_NL        or_IN       sat_IN            sr_ME        ti_ER       translit_small         wa_BE
ar_IN        ayc_PE       bs_BA       de_BE@euro  en_DK       es_CL  es_SV       fr_CH       gl_ES@euro      ik_CA               kok_IN            mai_IN  ne_NP         os_RU       sc_IT             sr_RS        ti_ET       translit_wide          wa_BE@euro
ar_IQ        az_AZ        byn_ER      de_CH       en_GB       es_CO  es_US       fr_FR       gu_IN           is_IS               ko_KR             mg_MG   nhn_MX        pa_IN       sd_IN             sr_RS@latin  tig_ER      tr_CY                  wae_CH
ar_JO        be_BY        ca_AD       de_DE       en_HK       es_CR  es_UY       fr_FR@euro  gv_GB           iso14651_t1         ks_IN             mhr_RU  niu_NU        pap_AN      sd_IN@devanagari  ss_ZA        tk_TM       tr_TR                  wal_ET
ar_KW        be_BY@latin  ca_ES       de_DE@euro  en_IE       es_CU  es_VE       fr_LU       ha_NG           iso14651_t1_common  ks_IN@devanagari  mi_NZ   niu_NZ        pa_PK       se_NO             st_ZA        tl_PH       ts_ZA                  wo_SN
ar_LB        bem_ZM       ca_ES@euro  de_LU       en_IE@euro  es_DO  et_EE       fr_LU@euro  he_IL           iso14651_t1_pinyin  ku_TR             mk_MK   nl_AW         pl_PL       shs_CA            sv_FI        tn_ZA       tt_RU                  xh_ZA
#語言確實博大精深,不過我們直奔主題,我們需要的只是中文,只要看到這個就足夠了
zh_CN

假如沒有怎麼辦,也確實是有可能的,那我們就需要安裝了

#ubuntu安裝
apt-get -y install language-pack-zh-hans language-pack-zh-hans-base
#centos安裝
yum install kde-l10n-Chinese
yum reinstall glibc-common

如果是一般的物理機,或者kvm/vmware的虛擬機,到了這一步,然後再source一遍,一般也能解決的了,然鵝,我的docker還是不行,真是ri了狗.

不過,就算他沒有,我們也可以自己造一個啊,聽起來很玄乎,但是真的可以,利用localedef命令來做

---------------------------------------------------

先看看這個命令的介紹:

localedef 命令

用途

轉化語言環境和字符集描述(charmap)源文件以生成語言環境數據庫。

語法

localedef [ -c ] [ -f Charmap ] [ -i SourceFile ] [ -L LinkOptions ] [ -m MethodFile ] LocaleName

參數

-c    就算髮出了警告消息,仍然強制語言環境表的創建。
-f CharMap    指定包含了字符符號映射以及將元素符號整理爲實際字符編碼的文件名稱。一個語言環境與且僅與一個代碼集關聯。如果沒有指定該標誌,那麼採用 ISO 8859-1 代碼集。注:完全支持系統提供的某些 CharMap 文件。然而,當用戶提供的正確定義的 CharMap 文件可能正常工作時,仍不能保證這樣使用的結果。
-i SourceFile    指定包含語言環境類別源定義的文件的路徑名。如果沒有給出此標誌,那麼源定義從標準輸入上讀取。
-L LinkOptions    將指定的鏈接選項發送給構建語言環境的 ld 命令。
-m MethodFile    指定描述構造語言環境時覆蓋的方法的方法文件的名稱。方法文件指定用戶提供的覆蓋現有定義的子例程以及包含指定的子例程的庫的路徑名。當構造語言環境對象的時候,localedef 命令讀取方法文件並使用入口點。指定的代碼集方法也可用來分析由 CharMap 變量指向的文件。注:要創建 64 位語言環境,方法文件必須將庫的路徑指定爲具有包含指定的子例程的兩個共享對象(一個 32 位,另一個 64 位)的單一壓縮文檔。對 32 位和 64 位共享對象指定不同的路徑導致 localedef 命令由於不兼容 XCOFF 格式而失敗。
LocaleName    指定要創建的語言環境名稱。它是後來可以用於訪問此語言環境信息的名稱。

----------------------------------------------------------

看完介紹,也確定有這個語言支持,那就來造一個吧

#造一箇中文的utf-8字符編碼,
#意思就是指定zh_CN的語言環境,然後指定UTF-8編碼,命名爲zh_CN.UTF-8
localedef -i zh_CN -f UTF-8 zh_CN.UTF-8
#在看看系統有沒有這個字符編碼沒有,
locale -a
C
POSIX
zh_CN.utf8
#可以看到存在了,在加載一下
source  /etc/profile

然後,一切都回歸正常,不再亂碼了.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章