因为日志处理需要,接触到 perl,虽然还未入门,但通过几个函数就可以发现其在文本处理上的威力确实名不虚传,更不用提正则表达式了。

假设有这样的应用场景:客户通过 ftp 客户端上传文件到接入端 ftp 服务器,接入端 ftp 服务器作为分布式存储系统的客户端,再将这些文件存入到后面的分布式存储服务器中。这个接入端 ftp 服务器要做的工作就是定时分析 ftp server(假设是 vsftpd,日志为 xferlog)的日志来获取客户上传的文件,再对这些文件做后续处理。客户上传时随时进行的,xferlog 的记录条数也随之增长。

perl 中通过 seek 函数可以很方便的做到,每一次脚本执行时,都将上一次脚本执行时 xferlog 的大小作为本次读操作的偏移量,用这个偏移量来调用 seek,本次处理完后再将该偏移量更新后存入到一个文件供下次脚本执行时读取。

如果是 bash 该如何实现呢?shell 内置的文件操作的命令很少,只好借助外部程序。我只想到了通过 dd 来实现:

touch file_size  
  
#读偏移量  
a=`cat readfile`  
echo $a  
  
#把偏移量作为dd的参数  
skip=$a  
  
#从上一次读取的地方开始复制到file2,(跳过上一次的字节,就是这次的开始)  
dd if=file1 of=file2 bs=1 skip=$skip  
#获得新增内容的大小(字节)  
size1=`wc -c file2 | awk '{print $1}'`  
#获取下次需要skip 的字节数  
sum=`expr $a + $size1`  
#记录偏移量  
echo $sum>file_size  
#进行本次处理  
while read line  
do  
    #do something  
done<file2  

perl 一个函数 seek 就可以搞定的事情,用这种方法却需要这么拐弯抹角。不光调用了 dd,而且还新增了一个临时文件。当然,这些只是从应用上看,效率上的差异暂时不是我要考虑的问题。