Linux下计算文件的MD5值

脚本功能

脚本使用Perl编写,计算文件的MD5值

脚本用途

服务器在安装完操作系统后,计算PATH变量里面所有的二进制文件的MD5、计算单个文件MD5值、计算某个目录(包括子目录)下所有的文件的MD5值记录到文件,等日后再生成一份,然后2份文件进行对比,即可知道这些文件是否又被改动过.

脚本用法(5种用法)


  1. 脚本名 -p                   [ > 输出的文件名]  ← 该功能是计算PATH变量里面所有文件的MD5值 
  2. 脚本名 文件1 文件2 文件3 ...  [ > 输出的文件名]  ← 该功能是计算指定文件的MD5值 
  3. 脚本名 目录1 目录2 目录3 ...  [ > 输出的文件名]  ← 该功能是计算指定目录下所有文件的MD5值 
  4. 脚本名 -c MD5文件1 MD5文件2  [ > 输出的文件名]  ← 该功能是比较同一个目录下所有文件生成的2次MD5文件中有哪些MD5值不一致 
  5. 脚本名 目录 -f MD5文件       [ > 输出的文件名]  ← 该功能是跟上面的功能类似,只是这个不生成文件直接比对

注意事项

不能对/proc目录进行计算
不能对/(根)进行计算,因为/里面包含/proc
不能对挂载在Linux上Windows的共享目录进行计算

脚本内容


  1. #!/usr/bin/perl
  2. use Digest::MD5;
  3. use File::Find;
  4.  
  5. # 2012-11-24 22:41 Leo chanyipiaomiao@163.com
  6. # Blog:http://linux5588.blog.51cto.com
  7.  
  8. #用法提示 
  9. $usage = "Usage: scriptname -p | Directory1 ... | File1 ... | -c MD5File1 MD5File2 | Directory -f MD5File [ > OUTFILE]"; 
  10. $usagecompare = "Usage: scriptname -c MD5File1 MD5File2 [ > OUTFILE]"; 
  11. $usagepath = "Usage: scriptname -p [ > OUTFILE]"; 
  12.   
  13. #判断命令行参数是否为空,为空 则直接计算PATH路径里面所有的二进制文件的MD5值,不为空  
  14. #如果第一个参数是目录,那么调用getDirectoryAllFileMD5 计算目录里面所有文件的MD5值 
  15. #如果第一个参数是文件,那么调用getSingleFileMD5 计算命令行参数里面所有文件的MD5值 
  16.  if (@ARGV) { 
  17.     my $arg = $ARGV[0]; 
  18.     if (-d $arg ) { 
  19.         if ($ARGV[1] eq '-f' && -T $ARGV[2]){ 
  20.             &compareWithLastMD5File($arg);  
  21.         } else { 
  22.             &getDirectoryAllFileMD5(@ARGV); 
  23.         } 
  24.     } elsif ( -f $arg ) { 
  25.         &getSingleFileMD5(@ARGV); 
  26.     } elsif ($arg eq '-c' && @ARGV == 3 ) { 
  27.         die "$usagecompare\n" unless (-T $ARGV[1] && -T $ARGV[2]); 
  28.         &compareWithTwoMD5Files; 
  29.     } elsif ($arg eq '-p') { 
  30.         die "$usagepath\n" unless (@ARGV == 1); 
  31.         &getPathBinFileMD5; 
  32.     } else { 
  33.         die "$usage\n"; 
  34.     } 
  35.  } else { 
  36.     die "$usage\n"; 
  37.  } 
  38.   
  39. #得到目录下所有文件(包括子目录)的MD5值 
  40.  sub getDirectoryAllFileMD5 { 
  41.     find(\&wantedPrint,@_); 
  42.  } 
  43.   
  44. #得到PATH变量里面所有的二进制文件的MD5值 
  45.  sub getPathBinFileMD5 { 
  46.     my @path = split /:/,$ENV{PATH};  
  47.     find(\&wantedPrint,@path); 
  48.  } 
  49.   
  50.  #得到单个文件的MD5值 
  51.  sub getSingleFileMD5 { 
  52.     foreach (@_) { 
  53.         if (-R $_) { 
  54.             print "$_ ",&getMD5($_),"\n"; 
  55.         } else { 
  56.             print "Can't read $_\n"; 
  57.             next; 
  58.         } 
  59.     } 
  60.  } 
  61.   
  62. #先生成该目录下所有文件的MD5值,然后跟上一次该目录的生成的MD5文件对比 
  63. #本次生成的MD5跟上一次生成的MD5文件比对,不一致的输出出来,同时将3个时间输出出来 
  64. #如果是新添加的文件则输出出来其3个时间值,atime mtime ctime 
  65.  sub compareWithLastMD5File { 
  66.     find(\&wantedHash,@_); 
  67.     my $md5file = $ARGV[2]; 
  68.   
  69.     open MD5FILE,"<","$md5file" or die "Can't read $md5file : $!\n"; 
  70.     my $lastMD5Filerecords = (@lastMD5FilerecordsArray = <MD5FILE>); 
  71.     my %lastMD5Hash = map { split } @lastMD5FilerecordsArray; 
  72.     close MD5FILE; 
  73.   
  74.     foreach (keys %thisMD5Hash) { 
  75.         $thisMD5Filerecords++; 
  76.     } 
  77.   
  78.     if ($thisMD5Filerecords >= $lastMD5Filerecords) { 
  79.         %hash1 = %thisMD5Hash; 
  80.         %hash2 = %lastMD5Hash; 
  81.     } else { 
  82.         %hash1 = %lastMD5Hash; 
  83.         %hash2 = %thisMD5Hash; 
  84.     } 
  85.   
  86.     foreach  (keys %hash1) { 
  87.         if (exists $hash2{$_}) { 
  88.             if ( $hash1{$_} ne $hash2{$_} ) { 
  89.                 ($atime,$mtime,$ctime) = &getFileAMCTime($_); 
  90.                 print "Different:$_ $hash1{$_} Atime:$atime Mtime:$mtime Ctime:$ctime\n"; 
  91.             } 
  92.         } else { 
  93.             if (-e $_) { 
  94.                 ($atime,$mtime,$ctime) = &getFileAMCTime($_); 
  95.                 print "Added:$_ $hash1{$_} Atime:$atime Mtime:$mtime Ctime:$ctime\n"; 
  96.             } else { 
  97.                 print "Deleted:$_ $hash1{$_}\n"; 
  98.             } 
  99.         } 
  100.     } 
  101.  } 
  102.   
  103. #比较2个生成的MD5文件(对同一个目录生成的),找出不同的或者不存在的 
  104.  sub compareWithTwoMD5Files { 
  105.     my ($md5file1,$md5file2) = ($ARGV[1],$ARGV[2]); 
  106.     open MD5FILE1,"<","$md5file1" or die "Can't read $md5file1 : $!\n"; 
  107.     open MD5FILE2,"<","$md5file2" or die "Can't read $md5file2 : $!\n"; 
  108.     my $file1record = (@file1record = <MD5FILE1>); 
  109.     my $file2record = (@file2record = <MD5FILE2>); 
  110.     close MD5FILE1; 
  111.     close MD5FILE2; 
  112.   
  113.     my %hashmap1 = map { split } @file1record; 
  114.     my %hashmap2 = map { split } @file2record; 
  115.   
  116.     if ($file1record >= $file2record) { 
  117.         %hash1 = %hashmap1; 
  118.         %hash2 = %hashmap2; 
  119.     } else { 
  120.         %hash1 = %hashmap2; 
  121.         %hash2 = %hashmap1; 
  122.     } 
  123.   
  124.     foreach  (keys %hash1) { 
  125.         if (exists $hash2{$_}) { 
  126.             if ( $hash1{$_} ne $hash2{$_} ) { 
  127.                 ($atime,$mtime,$ctime) = &getFileAMCTime($_); 
  128.                 print "Different:$_ $hash1{$_} Atime:$atime Mtime:$mtime Ctime:$ctime\n"; 
  129.             } 
  130.         } else { 
  131.             if (-e $_) { 
  132.                 ($atime,$mtime,$ctime) = &getFileAMCTime($_); 
  133.                 print "Added:$_ $hash1{$_} Atime:$atime Mtime:$mtime Ctime:$ctime\n"; 
  134.             } else { 
  135.                 print "Deleted:$_ $hash1{$_}\n"; 
  136.             } 
  137.         } 
  138.     } 
  139.  } 
  140.   
  141. #遍历条件,找到之后输出 
  142.  sub wantedPrint { 
  143.     if (-f $_ && -R $_) { 
  144.         print "$File::Find::name  ",&getMD5($_),"\n"; 
  145.     } 
  146.  } 
  147.   
  148. #遍历条件,找到之后形成一个HASH 
  149.  sub wantedHash { 
  150.     if (-f $_ && -r $_) { 
  151.         $thisMD5Hash{$File::Find::name} = &getMD5($_); 
  152.     } 
  153.  } 
  154.   
  155. #计算MD5值 
  156.  sub getMD5 { 
  157.     my $file = shift @_; 
  158.     open(FH, $file) or die "Can't open '$file': $!\n"; 
  159.     binmode(FH); 
  160.     my $filemd5 = Digest::MD5->new->addfile(FH)->hexdigest; 
  161.     close FH; 
  162.     return $filemd5; 
  163.  } 
  164.   
  165. #获取文件的atime,mtime,ctime 
  166.  sub getFileAMCTime { 
  167.     $filename = shift @_; 
  168.     my ($atime,$mtime ,$ctime) = (stat ($filename))[8,9,10]; 
  169.     $atime = &getTime($atime); 
  170.     $mtime = &getTime($mtime); 
  171.     $ctime = &getTime($ctime); 
  172.   
  173.     #将日期时间格式转换为比较友好的格式 
  174.     sub getTime { 
  175.         my $time = shift @_; 
  176.         my($sec,$min,$hour,$day,$mon,$year) = (localtime $time)[0..5]; 
  177.         $time = sprintf "%4d-%02d-%02d %2d:%02d:%02d",$year + 1900,$mon + 1,$day,$hour,$min,$sec; 
  178.         return $time; 
  179.     } 
  180.     return $atime,$mtime,$ctime; 
  181.  } 

 

时间: 2024-08-04 01:36:55

Linux下计算文件的MD5值的相关文章

php 遍历目录,生成目录下每个文件的md5值并写入到结果文件中_php实例

php 遍历目录,生成目录下每个文件的md5值并写入到结果文件中 实例代码: <?php /** * @author Administrator * */ class TestGenerate { public static $appFolder = ""; public static $ignoreFilePaths = array ( "xxxx/xxx.php" ); public static function start() { $AppPath =

计算文件的MD5值上传到服务器 下载验证文件是否被篡改

using System; using System.Windows.Forms; using System.Security.Cryptography; using System.IO; namespace 计算文件的MD5 {     public partial class Form1 : Form     {         public Form1()         {             InitializeComponent();         }         priv

我的Java开发学习之旅------&amp;gt;工具类:Java获取字符串和文件进行MD5值

ps:这几天本人用百度云盘秒传了几部大片到云盘上,几个G的文件瞬秒竟然显示"上传成功"!这真让我目瞪口呆,要是这样的话,那得多快的网速,这绝对是不可能的,也许这仅是个假象.百度了一下才发现所谓的"秒传"是常见的"忽略式"上传方式,就是您上传了一个文件名为111.exe,MD5为一个数,有一个网友以前也上传一个叫222.exe,MD5和您上传的文件MD5码一模一样,所以这个文件上传到服务器上的时间就很短了,这是因为别人上传过这个文件,您上传这个文件

vb.net 怎么获取一个文件夹所有文件的MD5值?

问题描述 大家好!谁能帮我写一段代码?vb.net怎么获取一个文件夹所有文件的MD5值?大家能不能提供源代码? 解决方案 解决方案二: 我给你分解一下1.获取每个文件的md5值2.遍历文件夹,如果是文件就调用上面函数计算3.输出计算值解决方案三: 将文件夹打包,然后对打包文件进行MD5计算或者遍历文件夹,然后对每一个MD5计算解决方案四: 给你写了一个完整的例子ImportsSystem.IOImportsSystem.Security.CryptographyImportsSystem.Lin

Linux下脚本文件的seq的学习

问题描述 Linux下脚本文件的seq的学习 B=seq -s " " -f"iconback%02g" 1 $A C=seq -s " " -f"img%0g" 1 $A 请问哪位知道如何让B,C 打印出来的值一一对应,例如:img1="iconback01",img2="iconback02".... 解决方案 seq没法支持两个变量,用awk来 awk 'BEGIN { for(i

Linux下删除文件下彻底删除文件

  在linux中删除文件与文件夹我们可以直接使用rm就可以删除了,彻底删除文件或文件夹我们可以使用shred命令来完成,下面我给大家介绍介绍. Linux删除文件夹命令 linux删除目录很简单,很多人还是习惯用rmdir,不过一旦目录非空,就陷入深深的苦恼之中,现在使用rm -rf命令即可. 直接rm就可以了,不过要加两个参数-rf 即:rm -rf 目录名字 删除目录.文件 rm(remove) 功能说明:删除文件或目录. 语 法:rm [-dfirv][--help][--version

Linux 下目录文件权限(命令)的查看和修改_Linux

Linux 下目录文件权限的查看和修改 在我的服务器下面有这几个文件夹 同时用ls -l也可以查看到这几个文件的权限. 看其中的assets文件一共有十位数,其中: 最前面那个 - 代表的是类型 中间那三个 rwx 代表的是所有者(user)拥有的权限 然后那三个 rwx 代表的是组群(group)拥有的权限 最后那三个 rwx 代表的是其他人(other)拥有的权限 r 表示文件可以被读(read) w 表示文件可以被写(write) x 表示文件可以被执行(如果它是程序的话) -表示相应的权

Linux下利用文件描述符恢复的成功失败实验

    数据误删除是作为初级运维人员常常遇到的"低级错误",一些有经验的老手有时也在疲劳.不冷静的情况下"马失前蹄".一旦误删除数据文件,尽快采用影响最小.最迅速的手段恢复数据库是第一要务. 恢复数据的方法很多,比如冷热备份.闪回数据库等等,如果是直接从操作系统OS层面删除数据文件,在Linux/Unix环境下,有一些优选手段可以使用.其中之一就是文件描述符(File Description).   1.聊聊File Description   不同的操作系统,在实

文件复制到其它地方然后计算它的MD5值

问题描述 现在要实现一个文件复制后接着计算出这个复制后的MD5值:但遇到一个问题!就是马上复制后拒绝MD5值的计算!就算文件用代码实现的复制也不能马上打开计算它的MD5!要怎么实现啊!我让进程Sleep会也不行啊!要怎么办怎么办啊??? 解决方案 解决方案二:TOP解决方案三:有什么报错信息吗解决方案四:对路径"\GAOWEILIPrintFloderTemplateSupervsielabel.tdd"的访问被拒绝.解决方案五:\GAOWEILI,局域网?你不是复制到本地吗解决方案六