十一月 9th, 2009

Putty登录后Vim中文乱码问题

Unix/Linux系统, by 陈威.
热度:

在用Telnet或Putty登录到远程Unix服务器后,vim是用户最常用的文档编辑工具之一。但在使用Telnet或Putty等字符界面工具远程登录服务器时,vim打开包含有中文内容的文件时经常会遇到中文乱码问题,这可能是由于Unix的默认编码方式、vim的默认编码方式以及终端所在操作系统的编码方式不一致导致的。

在安装WordPress的时候,我用vim打开wp-config-sample.php文件时发现里面的中文都变成了乱码,检查发现服务器上的vim全局配置中把默认编码设为了GB2312,而wp-config=sample.php文件的编码方式却是UTF-8。出于安全考虑,不可能通过修改vim的全局配置来解决这个中文乱码问题。不过Unix在每个用户的主目录中都有生成一个.vimrc的vim局部配置文件(如果没有该文件,用户可以自己建立此文件,只需保证其中的内容符合语法规定即可),这个配置文件规定了以此用户名登录的终端在调用vim命令时的默认配置。为了解决打开wp-config-sample.php时的乱码问题,我在.vimrc文件中添加了如下两行内容:

vim乱码问题 注意到上图中,修改了设置包括了termencoding, encoding和fileencodings三个选项,实现的功能是把用于终端的编码方式termencoding设为和vim的默认编码方式一致,并且设文件编码方式为utf-8, gb2312, gbk, ucs-bom和cp936(注意,这几个编码是有优先级关系的).

.vimrc配置文件中和编码相关的参数主要包括以下四个:

  • encoding

encoding参数设置的vim的内部编码方式,当我们设置了 ”encoding” 之后,Vim 内部所有的 buffer、寄存器、脚本中的字符串等都将都使用这个编码方式。Vim 在工作的时候,如果编码方式与它的内部编码不一致,它会先把编码转换成内部编码。如果工作用的编码中含有无法转换为内部编码的字符,在这些字符就会丢失。因此,在选择 Vim 的内部编码的时候,
一定要使用一种表现能力足够强的编码。由于 ”encoding” 选项涉及到 Vim 中所有字符的内部表示,因此只能在 Vim 启动的时候设置一次。在 Vim 工作过程中修改 ”encoding” 会造成非常多的问题。如果没有特别的理由,请始终将 ”encoding” 设置为 ”utf-8”。

  • termencoding

termencoding 是 Vim 用于屏幕显示的编码,在显示的时候,Vim 会把内部编码转换为屏幕编码,再用于输出。内部编码中含有无法转换为屏幕编码的字符时,该字符会变成问号,但不会影响对它的编辑操作。如果 ”termencoding” 没有设置,
则直接使用 ”encoding” 不进行转换。

  • fileencoding

fileencoding参数规定了vim默认的文件编码方式。当 Vim 从磁盘上读取文件的时候,会对文件的编码进行探测。如果文件的编码方式和 Vim 的内部编码方式不同,Vim 就会对编码进行转换。转换完毕后,Vim 会将 ”fileencoding” 选项设置为文件的编码。当 Vim 存盘的时候,如果 ”encoding” 和 ”fileencoding” 不一样,Vim 也会将文件转换成fileencoding定义的编码方式保存。通过打开文件后设置 ”fileencoding”,我们可以实现文件的编码转换。但是,由于”fileencoding” 是在打开文件的时候,由 Vim 进行探测后自动设置的。所以如果出现乱码,我们无法通过在打开文件后重新设置 ”fileencoding” 来纠正乱码。

  • fileencodings

fileencodings参数中可以设置多个编码方式以实现对文件编码的自动识别,因此它是fileencoding的复数形式。该参数的值是一个用逗号分隔的列表,列表中的每一项是一种编码的名称。当我们打开文件的时候,VIM 按顺序使用 fileencodings 中的编码进行尝试解码,如果成功的话,就使用该编码方式进行解码,并将 ”fileencoding” 设置为这个值,如果失败的话,就继续试验下一个编码。

Vim是如何支持多编码方式的呢?

  • Vim启动,根据 .vimrc 中设置的 encoding 的值来设置 buffer、菜单文本、消息文的字符编码方式。
  • 读取需要编辑的文件,根据 fileencodings 中列出的字符编码方式逐一探测该文件编码方式。并设置 fileencoding 为探测到的,看起来是正确的字符编码方式。
  • 对比 fileencoding 和 encoding 的值,若不同则调用 iconv 将文件内容转换为encoding 所描述的字符编码方式,并且把转换后的内容放到为此文件开辟的 buffer 里,此时我们就可以开始编辑这个文件了。注意,完成这一步动作需要调用外部的 iconv.dll,你需要保证这个文件存在于 $VIMRUNTIME 或者其他列在 PATH 环境变量中的目录里。
  • 编辑完成后保存文件时,再次对比 fileencoding 和 encoding 的值。若不同,再次调用 iconv 将即将保存的 buffer 中的文本转换为 fileencoding 所描述的字符编码方式,并保存到指定的文件中。同样,这需要调用 iconv.dll由于 Unicode 能够包含几乎所有的语言的字符,而且 Unicode 的 UTF-8 编码方式又是非常具有性价比的编码方式 (空间消耗比 UCS-2 小),因此建议 encoding 的值设置为utf-8。这么做的另一个理由是 encoding 设置为 utf-8 时, Vim自动探测文件的编码方式会更准确。在中文 Windows 里编辑的文件,为了兼顾与其他软件的兼容性,文件编码还是设置为 GB2312/GBK 比较合适,因此 fileencoding 建议设置为 chinese (chinese 是个别名,在 Unix 里表示 gb2312,在 Windows 里表示cp936,也就是 GBK 的代码页)。

关于Vim的更详细信息,可以参考Vim doc项目的网站:http://vimcdoc.sourceforge.net/

Vim的中文文档下载地址:http://vimcdoc.sourceforge.net/vim_user_manual_603.0.pdf

Back Top

Hello world! Favicon:网站特色小图标

Responses to “Putty登录后Vim中文乱码问题”

  1. 谢谢大飞~一起努力

  2. 真好,加油!

  1. telnet , (,2010年11月29日)

    telnet ,…

    Published on this site…

发表回复

Back Top

*
To prove you're a person (not a spam script), type the security text shown in the picture. Click here to regenerate some new text.
Click to hear an audio file of the anti-spam word