相信很多人(也可能只有我啦)使用樹莓派或新安裝 Linux 的時候,ssh 進 Server 後會遇到這個問題:
|
|
不只是 perl
出了問題(會用 perl
當例子只是因為他最好觸發),只要是 apt update
或是 git clone
的時候都會跳出這個問題,就是:
你沒設定好你的語系
同時這個問題困擾我很久了,因此趁時機來一次解決這個問題。
本篇就是來闡述發生了什麼事情。
Locale Setting
首先,第一種可能就是,語系檔沒安裝。如果有設定 LANG = "en_US.UTF-8"
,結果系統裡沒有該文檔,那當然會出現問題囉!
也就是明明全域變數中 LANG = "en_US.UTF-8"
,結果系統中沒有這個語系檔。
這種時候就是確認 /etc/locale.gen
中,有沒有把該語系 uncomment 掉,並且執行一次 locale-gen
來產生該語系檔案。或是 dpkg-reconfigure locales
來自動設定 locale 設定。如果是樹莓派的話,更簡單,執行 raspi-config
,並在選單中直接調整語系就行了。
最後重新啟動 shell,隨便執行一個需要語系的指令,確認是否解決問題。
以上指令都需要 sudo
來執行。
LC_CTYPE
但問題其實來自於這個東西:LC_CTYPE
。
最一開始的 Warning Log 中其實就顯示了:
|
|
至於為什麼會出問題,很明顯的,LC_CTYPE
跟 LANG
不匹配,又或是根本沒有語系與 LC_CTYPE
相符。
這點可以直接在 bash 中輸入 unset LC_CTYPE
試試看,將將,問題解決了。
所以一切的元兇就是這個變數,那這個變數怎麼來的呢?
只有 MacOS 的人才有這個問題,Windows 使用者可能完全沒感覺。
因為 MacOS 中,/etc/ssh/ssh_config
有這一行。
|
|
代表說「在 ssh
後,傳入這些變數進 Server。」
於是輸入 echo $LC_CTYPE
後,發現 MacOS 的 LC_CTYPE
果然長得跟 Server 裡的一模一樣,到這裡已經可以有頭緒該怎麼解決了。
怎麼解決?
這邊提供幾種思路。
Server Shell Profile 解決法
總之為何不要在 Server 中的 .profile
或是,.zprofile
(zsh) 中明確地宣告呢?這樣就能直接確保在登入 Server Shell 時,這個設定會被覆寫。
|
|
頭痛醫頭法
先 unset 本地的變數,然後再 ssh 進去,並且由於括號的特性(括號內變動會在離開括號時復原),執行完之後不會影響到 Local 的變數。<Server>
請帶入自己的 ip 跟 username。
|
|
修改 ssh config
這裡有兩種方法,分別是設定 Client 或是設定 Server。兩者擇一即可。
在自己的電腦上,也就是 Client 中,設定 /etc/ssh/ssh_config
。找到以下內容,並將該句註解掉。
|
|
或是在伺服器端中設定 /etc/ssh/sshd_config
。
|
|
結論
總之這次的問題來源在 MacOS 亂傳遞了變數。雖然不會影響使用,但就是看了很煩。
我會推薦修改自己電腦裡的 /etc/ssh/ssh_config
。因為大部分情況下其實用不到語系傳遞,還不如直接解決問題根源。
希望有幫助到有同樣問題的人。
Appendix. Locale Env
最後列出,LC 的家族們以及它的用途。
- LC_CTYPE: 字元分類及處理方式。
- LC_COLLATE: 字元順序與字串比較。
- LC_MESSAGES: 程式中用何種語言來顯示訊息。
- LC_MONETARY: 貨幣顯式格式。
- LC_NUMERIC: 數字顯式格式。
- LC_TIME: 日期與時間的顯式格式。
- LC_ALL: 此類別可以一次設定以上所有的類別。
- LANG: 作用類似 LC_ALL,也可用來一次設定所有的 locale 環境。