衆所周知,地球上的語言多種多樣,在計算機世界,自然也是要適應各種語言.我們安裝各種系統的時候也是明示了要選擇語言環境和支持的語言環境.
而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
然後,一切都回歸正常,不再亂碼了.