Linux环境下shell和vim中乱码原因及消除办法
shell和vim中乱码原因及消除办法##
在Linux下开发,经常遇到乱码问题:shell或者vim中显示不了中文,或者能够显示,但不能输入中文。每次都是上网去搜,或者同事告诉我一些命令来解决的。一直没有理解为什么会出乱码,本文就是想认真分析乱码问题的原因并找到解决之道。希望本文能够解决像我这样的菜鸟在Linux下shell和vim中遇到的乱码问题。读者们如果读完这篇文章后还是一头雾水,也不要着急[文章角度不同,不同的人的理解程度也不同],可以多看看类似的文章[文末的参考资料],等多遇到几次编码的问题,回头再看看这些文章,基本就明白了。可以结合这篇文章一起看 关于Unicode,字符集,字符编码,每个程序员都应该知道的事
基本概念##
首先得有一些背景概念需要理解一下:
字符[character]###
字符代表了字母表中的字符,标点符号和其他的一些符号。在计算机中,文本是由字符组成的。
字符集合[character set]###
由一套用于特定用途的字符组成,例如支持西欧语言的字符集合,支持中文的字符集合。字符集合只定义了符号和他们的语意,其实跟计算机没有直接关系。
现实生活中,不同的语系有自己的字符集合,例如藏文有自己的字符集合,汉文有自己的字符集合。到计算机的世界中,也有各种字符集合,例如ASCII字符集合,GB2312字符集合,GBK字符集合。还有一个其他字符集合的超集--Unicode字符集定义了几乎绝大部分现存语言需要的字符,是一种通用的字符集,来支持多语言环境(可以同时处理多种语言混合的情况)。各个国家和地区在制定编码标准的时候,“字符集合”和“字符编码”一般都是同时制定的。所以像ASCII字符集合一样,它也同时代表了一种字符的编码。
字符编码[character encoding]###
是一套规则,定义了在计算机内存中如何表示字符,是字符集中的每个字符与计算机内存中字节之间的转换关系,也可以认为是把字符数字化,规定每个“字符”分别用一个字节还是多个字节存储,用哪些字节来存储。例如ASCII编码[你没看错,它既是一种字符集合,也是一种字符编码],定义了英文字母和符号在计算机中的表示方式,是用一个字节来表示。Unicode字符集合,有好几种字符编码方式,例如变长度编码的UTF8,UTF16等。中文字符集也有很多字符编码,例如上文提到的GB2312编码,GBK编码等。
知乎上的这篇介绍字符编码,字体,iconv的文章很赞,内容浅显易懂。还有一篇很有名的有关Unicode和字符集的文章可以看看:The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!),网上有中文版。
之所以产生乱码,是因为显示的时候使用的字符编码方式和实际内容的字符编码不一致。就跟上文知乎上那个帖子里的小姑娘和小男孩的例子一样,显示所用的字符编码和实际内容的字符编码方式不一致,自然就看不懂对方写的是啥。所以想正确显示内容,有两个方法:
1. 统一一下,双方都使用同一种编码方式。
2. 把对方的内容转换成跟自己的编码方式一致的内容。可以用类似 iconv 这样的工具来完成
其次,还需要了解Linux系统中的这个东东:
语系locale###
可以通过命令: locale -a 来显示当前Linux系统支持的所有的语言环境。关于locale,强烈推荐看看Locale 详解,然后搞明白以下三个环境变量的优先级:LC_ALL>LC_*>LANG。locale相关的各个环境变量的作用参见这里。
乱码实战##
有了以上的知识储备,就可以解决以下问题了:
登录终端中显示的乱码问题###
用ssh客户端putty/securecrt 登录远程Linux服务器举例子:
要显示中文,首先确保bash中设置的语系是支持中文的,例如采用zh_CN.UTF8编码。可以简单的使用命令:export LANG=zh_CN.UTF8 来设置。如果此时putty中中文仍然是乱码,说明putty自身设置的编码跟刚才设置LANG的编码方式不一样,把putty中的编码方式改成UTF8。之后就可以显示并输入中文了。 如果你用的是bash,可以在~/.bashrc 配置文件中加入上述的命令。这样就不用每次登录后手动设置系统编码了。
vim中显示的乱码问题###
在vim中,有以下几个环境变量要理解[可以在vim中使用 :help 关键词 来查看文档]:
1. termencoding
Encoding used for the terminal. This specifies what character encoding the keyboard produces and the display will understand. For the GUI it only applies to the keyboard.
终端使用的编码方式,指定了键盘输出的编码格式和屏幕能够正常显示的编码方式
2. encoding
Sets the character encoding used inside Vim. It applies to text in the buffers, registers, Strings in expressions, text stored in the vim info file, etc. Changing this option will not change the encoding of the existing text in vim. The character encoding of files can be different from 'encoding'. This is specified with 'file encoding'. The conversion is done with icon() or as specified with ‘charconvert'
设置了vim内部缓冲区、寄存器、表达式等中存储的文本的编码方式。它与文件的编码 [ fileencoding ] 可以是不一样的。如果不一样,中间会经过iconv 转换
如果工作用的编码中含有无法转换为内部编码的字符,在这些字符就会丢失。因此,在选择 Vim 的内部编码的时候,一定要使用一种表现能力足够强的编码,例如UTF8,以免影响正常工作。
3. fileencoding
Sets the character encoding for the file of this buffer. When 'file encoding' is different from 'encoding', conversion will be done when reading and writing the file.文件自身的编码方式。如果fileencoding和encoding不一致,那么在读取和写入文件时,会对编码方式进行转换。
通过打开文件后设置 fileencoding,我们可以将文件由一种编码转换为另一种编码
4. fileencodings
This is a list of character encodings considered when starting to edit an existing file. When a file is read, Vim tries to use the first mentioned character encoding. If an error is detected, the next one in the list is tried. When an encoding is found that works, 'file encoding' is set to it. If all fail, 'file encoding' is set to an empty string, which means the value of 'encoding' is used.
Note that 'fileencodings' is not used for a new file, the global value of 'file encoding' is used instead.
是一个字符编码的列表。当vim打开一个文件时,会尝试使用列表中的第一个字符编码方式。如果检测到错误,就用列表中的下一个。当找到一个可以正常工作的字符编码方式后,file encoding就被设置成找到的字符编码方式。如果最后都失败了,fileencoding就被设置成空的,这意味者字符的编码方式就跟 encoding变量的值一样了。
这样通过这个列表,Vim可以自动判断文件的编码,自动判断失败时还可手动设定 fileencoding 来指定编码。因此,设置 fileencodings 的时候,一定要把要求严格的、当文件不是这个编码的时候更容易出现解码失败的编码方式放在前面,把宽松的编码方式放在后面。
当vim中遇到乱码时,基本都是由于vim没有能够正确地识别出文件的编码导致的。
首先保证终端里可以正常显示中文,然后使用命令 :set fileencoding=GBK 来设置vim中此文件的正确编码。可以使用命令 :set fileencoding? 查看vim识别出的文件编码。
推荐阅读##
如果您看了本篇博客,觉得对您有所收获,请点击右下角的“推荐”,让更多人看到!
Linux环境下shell和vim中乱码原因及消除办法的更多相关文章
- 【原】Linux环境下Shell调用MySQL并实现定时任务
对于一些周期性事务,我们可以在Linux下,使用shell脚本调用mysql数据库存储过程,并设置定时任务. 本来是要mysql数据库中创建事件任务来,定时执行存储过程,做数据传输的...使用cron ...
- linux环境下在springboot项目中获取项目路径(用于保存文件等)
//application.properties中设置:(file.path=static/qrfile/)//保存到static文件夹下的qrfile目录@Value("${file.pa ...
- vim 中乱码问题
在Linux下开发,经常遇到乱码问题:shell或者vim中显示不了中文,或者能够显示,但不能输入中文.每次都是上网去搜,或者同事告诉我一些命令来解决的.一直没有理解为什么会出乱码,本文就是想认真分析 ...
- 全世界最详细的图形化VMware中linux环境下oracle安装(二)【weber出品必属精品】
<ORACLE 10.2.05版本的升级补丁安装> 首先我们解压 $ unzip p8202632_10205_LINUX.zip 解压后我们会发现多出了个文件夹,他是:Disk1,进入D ...
- 全世界最详细的图形化VMware中linux环境下oracle安装(一)【weber出品必属精品】
安装流程:前期准备工作--->安装ORACLE软件--->安装升级补丁--->安装odbc创建数据库--->安装监听器--->安装EM <前期准备工作> 安装 ...
- 在linux环境下使用icepdf或pdfbox将pdf转化成图片是乱码解决
在linux环境下使用icepdf或pdfbox将pdf转化成图片是出现乱码,网上查发下是itextpdf生成pdf引用"STSong-Light"字体而linux环境下没有这个字 ...
- 【环境配置】Linux环境下下载、配置java环境、安装eclipse、建立eclipse快捷方式详解
一.首先是下载Java JDK 到目前为止的最新版本为(jdk1.8.0_60),有两种方式进行下载: 1.使用shell来进行下载,可使用如下命令直接进行下载: wget --no-check-ce ...
- Linux 环境下安装python相关
目录 Linux 环境下安装python相关 linux软件包管理工具之yum工具(如同pip3工具) yum源理解 下载阿里云的.repo仓库文件 ,放到/etc/yum.repos.d/ yum安 ...
- 在Linux环境下采用压缩包方式安装JDK 13
本文地址:https://www.cnblogs.com/oberon-zjt0806/p/11663731.html 可以,转载,出处,格式,懂?? 什么是JDK?? 好吧如果你不知道这个问题的话我 ...
随机推荐
- mapreduce中一个map多个输入路径
package duogemap; import java.io.IOException; import java.util.ArrayList; import java.util.List; imp ...
- In-Memory:内存优化表 DMV
在内存优化表的DMV中,有两个对象ID(Object ID): xtp_object_id 是内部的内存优化表(Internal Memory-Optimized Table)的ID,在对象的整个生命 ...
- JavaScript Date对象
本篇主要介绍 Date 日期和时间对象的操作. 目录 1. 介绍:阐述 Date 对象. 2. 构造函数:介绍 Date 对象的构造函数new Date()几种方式. 3. 实例方法:介绍 Date ...
- OpenCASCADE BRep Projection
OpenCASCADE BRep Projection eryar@163.com 一网友发邮件问我下图所示的效果如何在OpenCASCADE中实现,我的想法是先构造出螺旋线,再将螺旋线投影到面上. ...
- 套用JQuery EasyUI列表显示数据、分页、查询
声明,本博客从csdn搬到cnblogs博客园了,以前的csdn不再更新,朋友们可以到这儿来找我的文章,更多的文章会发表,谢谢关注! 有时候闲的无聊,看到extjs那么肥大,真想把自己的项目改了,最近 ...
- dedecms 后台栏目添加图片
前台调用栏目时需要显示图标,整理一下: 第一步:“系统->SQL命令工具” , 插入sql语句 alter table dede_arctype add typeimg varchar() 第二 ...
- JAVA的内存模型(变量的同步)
一个线程中变量的修改可能不会立即对其他线程可见,事实上也许永远不可见. 在代码一中,如果一个线程调用了MyClass.loop(),将来的某个时间点,另一个线程调用了MyClass.setValue( ...
- 在redis中使用lua脚本让你的灵活性提高5个逼格
在redis的官网上洋洋洒洒的大概提供了200多个命令,貌似看起来很多,但是这些都是别人预先给你定义好的,但你却不能按照自己的意图进行定制, 所以是不是感觉自己还是有一种被束缚的感觉,有这个感觉就对了 ...
- centos下开启ftp服务
如果要ftp访问linux需要安装ftp服务,vsftpd是Linux下比较好的的FTP服务器. 一.检查安装vsftp //检查是否安装vsftpd rpm -qa | grep vsftpd // ...
- ubuntu-14.04-server配置Jexus --安装步骤记录
作者:郝喜路 个人主页:http://www.cnicode.com 博客地址:http://haoxilu.cnblogs.com 说明:我是Linux菜鸟,自己尝试配置Jexus服务 ...