背景

Linux系统默认采用的UTF-8的编码(Unicode编码的一种),包括系统中的中英文和特殊字符,都是默认采用UTF-8编码。

而在国内,针对中文(包括基本的汉字、各少数民族文字、特殊字符等),有自己的编码标准(也称字符集),从前是GBK,到后来的GB18030-2000,现在是GB18030-2005,具体的编码原理机制和区别这里不展开,网上相关资料很多。

在国内的一些特殊行业中,对操作系统中使用的中文编码有严格的要求,如果使用Linux系统的话,就要求Linux能支持特定的编码,比如GBK和GB18030。

那么Linux是否支持UTF-8之外的其他字符集呢?

如何才能支持

从桌面OS的角度看,支持指定字符集,需要从几个层面支持:

  1. 内核。最底层的支持。
  2. C库。基础库和API支持,提供各种编码之间的转换接口。
  3. 图形库支持。在基础图形库的层面,提供相关的API接口。其他图形程序基于这些接口提供相关字符集支持。
  4. 桌面环境支持。图形桌面环境能处理相关字符集(基于相关图形库接口)。
  5. 字体库的支持。需要提供支持相应字符集的字体库。

现状

Linux主流发行版目前应该都是支持非UTF-8编码的,OS在上述4个层面都提供了基础的支持。但针对具体的字符集,支持程度还是有所不同,比如针对GB18030-2005字符集,目前绝大部分的Linux系统(包括Windows系统)都不能完美支持,主要问题孩子字体库方面,会存在少数字符乱码的情况。在不追求完美的情况下,还是能用的。

如果需要使用非UTF-8中文编码,需要进行手工配置,通常的发行版都没有提供相应的配置工具,需要手工修改配置。具体配置方法见后面小节。

另一方面,对于图形环境来说,情况相对更糟糕一些,如果要在某发行版中设置非UTF-8的中文编码,在进行了相应配置后,在图形环境中,使用起来通常还会遇到各种各样的问题,比如乱码、文件(夹)打不开等。这些问题基本都是因为图形环境中文件管理器对非UTF-8编码支持不好导致,关键还在 文件管理器 ,底层的图形库,比如GTK,基本都提供了完善的支持,只是上层应用(文件管理器)未能完美使用。

文件管理修改

根据验证,目前redhat系使用的主流的文件管理器,如nautilus和caja都不能完美支持非Utf-8编码,即使按后续章节方法进行完整配置后,在文件管理器中也会出现乱码,主要集中在左侧的places sidebar中对于special dirs的显示。

解决方法也很简单,修改相关部分代码,在显示之前进行编码转换即可。

Redhat 7配置方法

配置系统全局字符集

系统全局的字符集,本质上就是LANG或LC_ALL环境变量,该环境变量包含两部分内容:

  1. 系统语言
  2. 相应的字符集

典型设置如:LANG=zh_CN.UTF-8,即中文+UTF-8字符集,如果需要设置成GBK编码,则需要设置为:LANG=zh_CN.GBK

但是,具体在哪儿设置呢?不同的发行版,配置方法不一样,Redhat7中相应的配置文件为:/etc/locale.conf,在其中写入如下内容即可。

LANG=“zh_CN.GBK”

设置后,需重启生效。

配置文件管理器文件名字符集

文件管理器,如redhat默认使用的nautilus,即图形环境中管理文件的图形工具,也叫文件资源浏览器,常规理解即点击“我的电脑”后运行的程序。

文件管理器中可以进行文件(夹)创建、移动、重命名等操作,这些操作后的最终生成的文件名使用的编码,都依赖于文件管理器自身对字符集的支持。

nautilus对不同的字符集提供的比较完整的支持(确切的说应该是GTK提供了完整的支持),并提供了相应的配置框架,具体来说,只需要设置G_FILENAME_ENCODING=环境变量即可,比如要使用GBK编码,只需将其设置为:

G_FILENAME_ENCODING="GBK"

对于不同的发行版,设置的位置也不同,取决于使用的登录管理器,redhat7默认使用GDM作为登录管理器,只需要在/etc/gdm/Xsession脚本的前面位置(第一有效代码行,不包括注释和#!/bin/bash行)加入如下行即可:

export G_FILENAME_ENCODING="GBK"

配置主目录special dirs使用的字符集

默认情况下,每个用户的主目录(/home/<用户名>/)中都会默认创建几个special目录,比如“图片”“视频”“下载”之类的,在redhat7中这些目录是在用户第一次登录时,通过xdg-user-dirs组件创建的,这些目录的创建也涉及字符集问题,而xdg-user-dirs组件也提供了相应的配置选项,具体来说,只需要修改/etc/xdg/user-dirs.conf文件中的 **filename_encoding** 配置项即可。以GBK编码为例,修改后的配置文件内容示例如下:

enabled=True
filename_encoding=GBK

配置终端使用的字符集

在Redhat 7图形环境中,默认打开的终端使用的默认字符集为UTF-8,如果设置为其它编码,则需要修改相应的设置,设置步骤为:

  1. 选择终端菜单: “终端-》设定字符编码-》添加或删除…
  2. 在弹出的对话框列表中选择新编码(如GBK),选添加。
  3. 重新选择终端菜单: “终端-》设定字符编码-》新添加的编码

处理已有的UTF-8编码的内容

对于已经在UTF-8编码环境中创建的文件(夹),比如安装完成启动后,再修改系统的字符集为非UTF-8,此时如果已经通过图形环境登录过系统,这主目录中会自动通过xdg-user-dirs组件创建相应的special目录,并同时创建~/.config/user-dirs.dirs配置,这些目录和配置默认是UTF-8编码,这些目录会在系统字符集修改为非UTF-8字符集后,显示成乱码,如果要解决这个问题,有两种方式:

  1. 在安装完成后首次启动后,进入文本界面,在其中完成上述的所有配置(终端配置除外),然后重启。即在xdg-user-dirs组件创建目录之前完成字符集的设置。
  2. 对于已经创建了UTF-8编码的文件(夹)时,可以通过convmv工具进行编码转换:(使用convmv工具前,需要先安装相应组件)

    yum install -y convmv convmv -f utf-8 -t gbk –notest <文件(夹)名>

另外,需要删除已有的user-dirs.dirs配置(针对在修改字符集之前登录过的用户):

rm -f ~/.config/user-dirs.dirs