0、背景

在生成注册号开发中,初步的规律已经得到。整个某省分为175个区域,累计注册号>1亿条。

生成注册号的前期程序都是在程序里面构造的,且充分验证ok,某区域的有效数据累计2万条为证据。

为了实现程序自动化生成一个省的所有注册记录,特采取了读配置的策略。如:前6位机关号写入配置文件。

结果就跑了4个小时以上生成了近一亿条数据。本来,到这里也就完了。

可是,Bug出现了。

当我在将近2万条实验成功的数据导入到新表中时,发现前14位相同的注册号,第15位注册号竟然不同。

很明显是有Bug了。

一个换行符引发的思考!_unix

1、Bug溯源

加日志打印后,症状:正常打印应该为:”str1=270000001800015”,
实际输出结果为:00015=2700000018。
有明显的错乱,内存越界的痕迹。

步骤1——初步想到的是:栈变量内存分配的问题。

(1)配置了空间过大,改成同样大小14个长度的字节数。 验证后,错误结果依旧。
(2)改成堆内存分配,每次进入循环分配内存,退出循环释放内存。验证后,错误结果依旧。
此过程反反复复,接近20分钟。

步骤2——进一步跟踪,字符串的每一个字符都打印出来。当以10进制打印字符的时候,明显的第7个字符那里有很大猫腻。

再仔细想。前6个字符是从文件中读入的。多了个回车符。

步骤3——初步敲定原因。

为了编码的方便,我在windows下编辑的文件,机关号(前6位)是直接从构造好的Excel中拷贝过去的。
这就导致了如下内容:
(1)结束符导致读到的第7个字符为回车符”\r”,不正确。
(2)导致序列号的第7-15位向前错1位。
(3)最终导致出现验证码出错。
整个过程下来耗费近1个小时时间。

2、解决方案:

dos2unix 转为unix下的文件格式。
Centos 环境下执行:dos2unix *.txt

3、知识点备忘

(1)换行符:

1).windows中的换行符是\r\n,
2). linux/unix下的换行符是\n。
其中:
回车符:\r=0x0d (13) return; #回车
换行符:\n=0x0a (10) newline。#换行

(2) unix2dos命令详解:

对应的将UNIX格式文本文件转成成DOS格式的是unix2dos命令。

dos2unix命令用来将DOS格式的文本文件转换成UNIX格式的(DOS/MAC to UNIX text file format converter)。
再次强调:
DOS下的文本文件是以\r\n作为断行标志的,表示成十六进制就是0D 0A。
而Unix下的文本文件是以\n作为断行标志的,表示成十六进制就是 0A。
DOS格式的文本文件在Linux底下,用较低版本的vi打开时行尾会显示^M,而且很多命令都无法很好的处理这种格式的文件,如果是个shell脚本。
而Unix格式的文本文件在Windows下用Notepad打开时会拼在一起显示。因此产生了两种格式文件相互转换的需求。

4、结语

(1)dos2unix转换是在公司里面非常常用的命令。最近一段时间由于用的少,竟然给忘记。险些误了大事。

(2)遇见Bug,不要慌张,多角度思考。同理的下午两表合并的Bug,最终我的解决方案改为:解析原有2万多条有效数据的表,然后解析的同时,将结果Update到新表中。效率相对较高。

(3)换一个思路,或许会“柳暗花明”、“豁然开朗”。同时操作一个表导致的死锁问题,最终的解决方案就是通过: show processlist;找到Locked Id, 然后kill 对应Id掉即可。

一个换行符引发的思考!_unix_02


作者:铭毅天下