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

目录
打赏
0
0
0
0
345
分享
相关文章
7种比较Linux中文本文件的最佳工具
7种比较Linux中文本文件的最佳工具
7种比较Linux中文本文件的最佳工具
|
9天前
|
【Linux】 Linux文件I/O常见操作技巧
以上就是Linux文件I/O操作的一些技巧,接纳它们,让它们成为你在Linux世界中的得力伙伴,工作会变得轻松许多。不过记住,技巧的运用也需要根据实际情况灵活掌握,毕竟,最适合的才是最好的。
62 28
SecureCRT & SecureFX 9.6.3 for macOS, Linux, Windows - 跨平台的多协议终端仿真和文件传输
SecureCRT & SecureFX 9.6.3 for macOS, Linux, Windows - 跨平台的多协议终端仿真和文件传输
266 4
SecureCRT & SecureFX 9.6.3 for macOS, Linux, Windows - 跨平台的多协议终端仿真和文件传输
|
7天前
|
"unzip"命令解析:Linux下如何处理压缩文件。
总的来说,`unzip`命令是Linux系统下一款实用而方便的ZIP格式文件处理工具。本文通过简明扼要的方式,详细介绍了在各类Linux发行版上安装 `unzip`的方法,以及如何使用 `unzip`命令进行解压、查看和测试ZIP文件。希望本文章能为用户带来实际帮助,提高日常操作的效率。
54 12
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
432 76
|
1月前
|
Linux系统下快速批量创建和删除文件的方法
总的来说,使用shell脚本来批量处理文件是一种非常强大的工具,只要你愿意花时间学习和实践,你会发现它能大大提高你的工作效率。
98 19
|
2月前
|
Linux基础:文件和目录类命令分析。
总的来说,这些基础命令,像是Linux中藏匿的小矮人,每一次我们使用他们,他们就把我们的指令准确的传递给Linux,让我们的指令变为现实。所以,现在就开始你的Linux之旅,挥动你的命令之剑,探索这个充满神秘而又奇妙的世界吧!
93 19
|
2月前
|
Linux 常用文件查看命令
`cat` 命令用于连接文件并打印到标准输出,适用于快速查看和合并文本文件内容。常用示例包括:`cat file1.txt` 查看单个文件,`cat file1.txt file2.txt` 合并多个文件,`cat > filename` 创建新文件,`cat >> filename` 追加内容。`more` 和 `less` 命令用于分页查看文件,`tail` 命令则用于查看文件末尾内容,支持实时追踪日志更新,如 `tail -f file.log`。
94 5
Linux 常用文件查看命令
|
1月前
|
如何创建Linux交换文件?Linux交换文件最新创建方法
Swap是Linux中的虚拟内存空间,用于在物理内存不足时将非活动进程移至磁盘,从而优化活动进程的性能。通过创建交换文件(如1GB),可灵活调整交换空间而无需重新分区。步骤包括:使用`fallocate`或`dd`创建文件、设置权限 (`chmod 600`)、格式化 (`mkswap`)、启用交换 (`swapon`)、修改`/etc/fstab`以持久化配置,以及调整`vm.swappiness`值(默认60,建议从10开始)来平衡内存与交换的使用。最后通过`swapon -s`检查状态并重启生效。此方法适用于VPS和专用服务器,需以root用户操作。
67 2
Linux|Transfer.sh 轻松实现文件共享
Linux|Transfer.sh 轻松实现文件共享
Linux|Transfer.sh 轻松实现文件共享
下一篇
阿里云OSS
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等