linux下用文本处理器处理二进制文件后的终端乱码问题

简介:
乱码!乱码!在linux终端上不小心或不在意cat了一个elf文件,或者仅仅是cat了一个word文档,整个shell就成了乱码,连提示符都不例外,很多人包括我之前都是索性关掉shell,然后重新打开一个shell,这linux的终端未免也太脆弱了吧,一向宣称进程间隔离的linux系统,怎能对待如此重要终端如此如此,盈天地之唯美,只在一草一木之间,然linux却如何做到。
     事实上,在彻底解决问题之前,我不得不先为linux平反,首先造成终端乱码的不是linux设计的漏洞,而是用户的有意为之,另外即使用户有意为之,如果你换一下终端类型,cat同样的二进制文件就可能不再乱码,最后,要记住,不是linux本身出了问题,问题在于字符集。
     用户的有意为之怎讲?用户并没有对终端进行设置啊!是的,用户没有显式的设置,可是却隐式地进行了设置,此所谓隐式是cat或者vi等“文本”查看/编辑器对终端进行了设置,想理解这个就必须对终端有一个深入的理解,这里不再介绍,需要者自然google之。每个终端为了回显字符必有一个字符集配置,每个终端为了实现功能,必有一个命令解释规范,对于最古老的vt100终端类型来说也是这样,如果很多终端对vt100兼容,vt100有两种字符集设置,称为G0和G1,注意,这G0和G1只是一个中间层,并没有指向最后的字符映射表,用户可以为每一个字符集配置其指向的字符映射表,这字符映射表才最终地进行了字符显示时的解释。我们在解决问题之前先来手动制造一次乱码,解决错误之前首先明白为什么错。要手动制造乱码,由刚刚介绍的理论得知,只要将G0或者G1指向一个错误的字符映射表就可以了,但是怎么做到呢?于是我们就不得不熟悉一下相关的vt100的控制命令了,vt100的控制命令均是以ESC键开头,后面跟一个键序列,比如ESC+[+2+J的意思就是清屏,那么我们测试一下这个清屏命令,用echo -e来测试,esc键是0x1b,于是echo -e '/x1b[2J'就实现了清屏,既然知道了vt100的控制命令写法,我们接下来来一次手工乱码,还是先来一段理论,很多系统用四张字符映射表,分别设为a,b,c,d,一般a为我们使用的映射表,具体这四张映射表分别有何属性,本文不再介绍,请google之,关键词为vt100,那么只要我们将字符映射表设置为b,c,d就可能造成乱码了,我们不妨试一下,配置字符映射表的命令是ESC+(B/0/U/K(G0字符集)和ESC+)B/0/U/K(G1字符集),于是我们来一个echo -e '/x1b(0',看看是不是乱码,如果不是就说明当前的字符集可能是G1,那么就试试echo -e '/x1b)0',很多人看到的结果已经是乱码了,这就说明我们手工成功制造了乱码事件,怎么改回来呢?十有八九是echo -e '/x1b(B'或者echo -e '/x1b)B',注意以上命令可以用重定向的方式进行,比如echo -e '/x1b(0'>/dev/ttyX等等,否则一旦终端乱码了,你也就只能盲打了。
     于是,很多问题不用再解释了,cat或者vi本来就不是让你用来处理二进制文件的,以cat为例,它基本就是下面的处理过程:
while(...) {
    read(...);
    write(..)
}
在write的时候,一旦二进制序列中用上面的echo -e '/x1b(0'(或者U,K)那就麻烦了,cat在你不知道的情况下将'/x1b(0/u/k'写入了终端,而所有人都不能保证你的二进制文件中没有那样的序列,但是如果那是文本文件,除了你指明的转义,一个"/x"一般就被解释成了一个字符串而不是控制字符,也就是说,文本文件的任何处理都是用户指定的,用cat/vi处理二进制文件本身就是误用。在你使用vt100终端的情况下,cat /usr/bin/test试一下吧,然后再echo -e '/x1b(B'恢复之,另外在终端上,我们也可以使用快捷键,比如ctrl+v+n可以将字符集从G0切换到G1,如果G0和G1的字符映射表设置得不同或者不兼容,那么就会出现乱码,用ctrl+v+o恢复之,其实这里的ctrl+v+n/o和/xe//xf是一回事,具体可以查看一下键码的知识。用vi我们也可以测试一下,vi一个文件,然后按ctrl+v,表明接下下插入控制字符,之后按ctrl+n,然后正常输入字符,保存,退出,然后cat该文件,乱之!

     好了,这下问题解决了,那么能否彻底解决这个问题呢?事实上可以的,为了防止二进制文件中的转义序列的write写入将G0切换到G1,那么就将G0和G1的字符映射表设置成同一个,为了防止二进制转义序列改变G0或者G1的字符映射表,那么就在每次处理完的时候重新恢复字符映射表的原始设置,不过,最好额办法不是为系统增加系统的鲁棒性,而是让各个程序各司其职,不要误用。还有一种方式就是使用健壮性比较好的终端,比如ansi以及linux终端等等,而放弃使用vt100兼容终端,使用rset程序修改之。



 本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1271868

相关文章
|
1月前
|
Linux 数据安全/隐私保护 Windows
命令方式:window向linux传文件
【10月更文挑战第6天】本文介绍了如何在Linux系统中通过命令`ip a`获取IP地址,并在Windows系统下使用CMD命令行工具和SCP命令实现文件传输。示例展示了如何将D盘中的`mm.jar`文件上传至IP地址为192.168.163.122的Linux系统的/up/目录下,最后在Linux系统中确认文件传输结果。
238 65
|
25天前
|
运维 安全 Linux
Linux中传输文件文件夹的10个scp命令
【10月更文挑战第18天】本文详细介绍了10种利用scp命令在Linux系统中进行文件传输的方法,涵盖基础文件传输、使用密钥认证、复制整个目录、从远程主机复制文件、同时传输多个文件和目录、保持文件权限、跨多台远程主机传输、指定端口及显示传输进度等场景,旨在帮助用户在不同情况下高效安全地完成文件传输任务。
177 5
|
25天前
|
Linux Shell 数据库
Linux文件查找新姿势:总有一种你没见过
【10月更文挑战第18天】文件查找是Linux用户提升工作效率的重要技能。本文介绍了几种实用的文件查找方法,包括基础的`find`命令、快速的`locate`和`mlocate`、高效的`fd`工具、以及结合`grep`和`rg`进行内容搜索。此外,还提供了编写Shell脚本和使用图形界面工具的建议,帮助你更灵活地管理文件。
62 3
|
1月前
|
Ubuntu Linux Python
Tkinter错误笔记(一):tkinter.Button在linux下出现乱码
在Linux系统中,使用Tkinter库时可能会遇到中文显示乱码的问题,这通常是由于字体支持问题导致的,可以通过更换支持中文的字体来解决。
115 0
Tkinter错误笔记(一):tkinter.Button在linux下出现乱码
|
7天前
|
Linux 开发工具 Perl
在Linux中,有一个文件,如何删除包含“www“字样的字符?
在Linux中,如果你想删除一个文件中包含特定字样(如“www”)的所有字符或行,你可以使用多种文本处理工具来实现。以下是一些常见的方法:
31 5
|
7天前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
23 6
|
7天前
|
Linux
在 Linux 系统中,`find` 命令是一个强大的文件查找工具
在 Linux 系统中,`find` 命令是一个强大的文件查找工具。本文详细介绍了 `find` 命令的基本语法、常用选项和具体应用示例,帮助用户快速掌握如何根据文件名、类型、大小、修改时间等条件查找文件,并展示了如何结合逻辑运算符、正则表达式和排除特定目录等高级用法。
32 6
|
8天前
|
监控 Linux Perl
Linux 命令小技巧:显示文件指定行的内容
在 Linux 系统中,处理文本文件是一项常见任务。本文介绍了如何使用 head、tail、sed 和 awk 等命令快速显示文件中的指定行内容,帮助你高效处理文本文件。通过实际应用场景和案例分析,展示了这些命令在代码审查、日志分析和文本处理中的具体用途。同时,还提供了注意事项和技巧,帮助你更好地掌握这些命令。
21 4
|
14天前
|
Linux 开发工具
linux文本管理命令
本文档介绍了Linux系统中常用的文本处理命令,包括`echo`、`cat`、`head`、`tail`、`wc`、`less`、`grep`以及重定向符号的使用方法和练习题。此外,还详细讲解了VIM编辑器的特点、工作模式、常用快捷键和高级技巧,帮助用户高效地进行文本编辑和处理。
28 4
|
14天前
|
网络协议 Linux
linux系统重要文件目录
本文介绍了Linux系统中的重要目录及其历史背景,包括根目录、/usr、/etc、/var/log和/proc等目录的结构和功能。其中,/etc目录下包含了许多关键配置文件,如网卡配置、DNS解析、主机名设置等。文章还详细解释了各目录和文件的作用,帮助读者更好地理解和管理Linux系统。
38 2