Linux 下的 locale 机制

in #linux8 years ago

localedef

localedef 是用来生成 locale 的工具. localedef 能够读取 locale 定义文件, 以及 charmap 文件, 然后编译他们, 将编译好的二进制的 locale 数据库放在 /usr/lib/locale 目录里 (这个目录不是绝对的, 你可以通过 localedef --help 查看编译好的 locale 数据库文件放在哪里), 然后 Linux 系统中一些会使用到 locale 的程序 (基本上是使用 GNU libc 库的程序) 就能够找到并使用这些 locale.

生成了相应的 locale 数据库文件之后, 就可以设置 LC_* 环境变量为那个生成的 locale (一般我们是直接设置 LANG 变量). 然后, 支持 i18n 的程序就会根据这些环境变量来向用户展示信息, GNOME, KDE 开发的程序一般都支持 i18n, 比如 gedit, 因为 GNOME 的程序基本都使用 GTK, KDE 的程序基本都使用 Qt, 而 GTK, Qt 早已经支持 i18n 了.

我的系统里有个 GTK 的简单轻量的文字编辑软件, 叫做 leafpad, 当我在终端运行 (下面两行一定要在同一个终端运行):

$ LANG=en_US.UTF-8$ leafpad

打开的 leafpad 的菜单, 关于信息都是英文的. 当我这样运行时:

$ LANG=zh_CN.UTF-8$ leafpad

打开的 leafpad 的菜单, 关于信息就都是中文的了. (我的系统上已经编译了 en_US.UTF-8, zh_CN.UTF-8 这两种 locale)

你可以用 locale 命令来查看你的系统当前安装了 (编译了) 多少 locale.

locale definition file

locale 定义文件, 每一个文件会包含某个 locale 的所有信息 (LC_CTYPE 信息, LC_MESSAGE 信息等等), 这文件包含的也是 localedef 命令生成这个 locale 所需要的信息.

locale 定义文件一般位于 /usr/share/i18n/locales 目录中, 不用担心, localedef 自己会找到它们, 你可以通过 localedef --help 来查看与 locale 相关的目录.

localedef 读取 /usr/share/i18n/locales 目录里的 locale 定义文件, 将其编译之后生成二进制文件然后放到 /usr/lib/locale 目录下 (这个目录也可以通过 localedef --help 命令知晓). localedef 可以将编译好的每一个 locale 在 /usr/lib/locale 目录下单独创建一个子目录, 也可以将编译好的 locale 附加到 /usr/lib/locale/locale-archive 文件里 (通过 --add-to-archive 选项控制).

编译 locale 还需要 charmap 文件, 这种文件一般位于 /usr/share/i18n/charmaps 目录下, 这也是可以通过 localedef --help 命令知晓的.

locale

locale 命令是用来获取当前 locale 环境的信息的. 根据其 man 手册的描述, 当不带参数调用 locale 时, 它会读取当前 locale 环境的各个 category, 即各个 LC_* 环境变量, 将其打印到标准输出.

如果用户没有定义那么多的 LC* 环境变量, 那么 locale 读取的就是 LANG 环境变量, 并将没有定义的 LC 打头的环境变量设为 LANG 变量的值.

这和 GNU libc 的标准是一致的 (当然, locale 毫无疑问也使用了 glibc 库, setlocale() 调用什么的), GNU libc 库的 setlocale(int category, const char locale) 调用是这样的, 如果 locale 参数是 "", 那么对应的 category 的值将会从环境变量里面找, 首先是找 LC_ALL, 如果 LC_ALL 没有定义那就根据 category 的名字找对应的 LC (比如 LC_CTYPE), 如果还是没找到, 那最后就找 LANG.

locale-gen

locale-gen 是各大发行版所带的工具, 它可以认为是 localedef 的 wrapper, 为了让用户更方便的生成 locale. /etc/locale.gen, /etc/locale.alias 也是发行版带的配置文件, 不是 Linux 原生的 locale 机制带的.

发行版的这一套机制能让用户操作起来更方便, 本来编译 locale 的话, 用户需要自己调用稍麻烦一些的 localedef 命令, 指定相应的 locale 定义文件和 charmap 文件, 还要指定二进制数据库的路径, 但是使用 locale-gen, 这些就不必用户操心了.

用户只要去 /etc/locale.gen 文件里, 把想要生成的 locale 取消注释, 然后运行 locale-gen, locale-gen 就会去检查 /etc/locale.gen 里没有被注释的行然后调用 localedef 并传以相应的参数生成相应的 locale.

参考

  1. man localedef
  2. man -a locale
  3. 介绍了 i18n: https://www.debian.org/doc/manuals/intro-i18n/index.en.html#contents
  4. Debian 系统的 locale 机制介绍: https://www.debian.org/doc/manuals/debian-reference/ch08.en.html

Coin Marketplace

STEEM 0.09
TRX 0.31
JST 0.031
BTC 107165.05
ETH 3871.84
USDT 1.00
SBD 0.59