一般来说,如果没有进行过特殊配置的话(比如说我们用 debootstrap 安装的系统),其默认 locale 会是 POSIX,我们使用 locale 命令可以看到这个情况。
# locale LANG= LANGUAGE= 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=
C 是系统默认的 locale,而 POSIX 是 C 的别名,因此这里看到的情况就是默认的 C Locale。它所指定的属性和行为由 ISO C 标准所指定。当我们新安装完一个系统时,默认的 locale 就是 C 或 POSIX。我们这里说的 C 其实就是 ASCII 编码。
但是我们同样也知道,标准的 ASCII 字符集中是不包含中文、日文等字符的,因此如果 POSIX 作为系统默认的 locale,那么会遇到在 SSH 下无法正确显示这些字符的问题,会直接按字节解析为 ASCII 转义字符,因此要想更正这个情况只有修改系统默认的 locale。
通过 locale -a 可以查看当前系统可用的所有 locale:
# locale -a C C.UTF-8 POSIX en_US.utf8
显然,en_US.utf8 是一个好选择。
下面贴过来一段对上文中提及的 LC_* 环境变量的接释:
- LANG
LANG的优先级是最低的,它是所有 LC_* 变量的默认值。下方所有以 LC_ 开头变量(不包括LC_ALL)中,如果存在没有设置变量值的变量,那么系统将会使用 LANG 的变量值来给这个变量进行赋值。如果变量有值,则保持不变,不受影响。可以看到,我们上面示例中的输出中的 LC_*变量的值其实就是 LANG 变量决定的 - LC_CTYPE
用于字符分类和字符串处理,控制所有字符的处理方式,包括字符编码,字符是单字节还是多字节,如何打印等,这个变量是最重要的。 - LC_NUMERIC
用于格式化非货币的数字显示。 - LC_TIME
用于格式化时间和日期。 - LC_COLLATE
用于比较和排序。 - LC_MONETORY
用于格式化货币单位。 - LC_MESSAGES
用于控制程序输出时所使用的语言,主要是提示信息,错误信息,状态信息, 标题,标签, 按钮和菜单等。 - LC_PAPER
默认纸张尺寸大小 - LC_NAME
姓名书写方式 - LC_ADDRESS
地址书写方式 - LC_TELEPHONE
电话号码书写方式 - LC_MEASUREMENT
度量衡表达方式 - LC_IDENTIFICATION
locale对自身包含信息的概述 - LC_ALL
它不是环境变量,它是一个宏,可通过该变量的设置覆盖所有的 LC_* 变量。这个变量设置之后,可以废除 LC_* 的设置值,使得这些变量的设置值与 LC_ALL 的值一致,注意,LANG 变量不受影响。在这里,这个宏操作就是用 LC_ALL 的值去覆盖 LC_* 的变量值
从描述中可以看出,优先级级别:LC_ALL > LC_* > LANG
注意:定义这么多变量在某些情况下是很有用的,例如,当我需要一个能够输入中文的英文环境,我可以把 LC_CTYPE 设定成 zh_CN.GB18030,而其他所有的项都是 en_US.UTF-8。
如果我们要修改这个默认的变量,可以在自己的 ~/.bashrc 中进行 export,比如我加入了这两行:
export LANG=en_US.utf8 export LC_CTYPE=en_US.utf8
之后重新登录一下就可以正常显示 Unicode 字符了。