脚本功能
脚本使用Perl编写,计算文件的MD5值
脚本用途
服务器在安装完操作系统后,计算PATH变量里面所有的二进制文件的MD5、计算单个文件MD5值、计算某个目录(包括子目录)下所有的文件的MD5值记录到文件,等日后再生成一份,然后2份文件进行对比,即可知道这些文件是否又被改动过.
脚本用法(6种用法)
- 脚本名 -p [ >
- 脚本名 -p -f MD5文件 [ > 输出的文件名] ← 该功能是计算PATH变量里面所有文件的MD5值并跟上一次生成的MD5文件相对比
- 脚本名 文件1 文件2 文件3 ... [ >
- 脚本名 目录1 目录2 目录3 ... [ >
- 脚本名 -c MD5文件1 MD5文件2 [ >
- 脚本名 目录 -f MD5文件 [ > 输出的文件名] ← 该功能是跟上面的功能类似,只是这个不生成文件直接比对
注意事项
不能对/proc目录进行计算
不能对/(根)进行计算,因为/里面包含/proc
不能对挂载在Linux上Windows的共享目录进行计算
脚本内容
【第二版】
1. #!/usr/bin/perl
2. use
3. use
4.
5. # 2012-12-16 15:24 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 | -p -f MD5File [ > OUTFILE]";
12.
13. #判断命令行参数是否为空,为空 则直接计算PATH路径里面所有的二进制文件的MD5值,不为空
14. #如果第一个参数是目录,那么调用getDirectoryAllFileMD5 计算目录里面所有文件的MD5值
15. #如果第一个参数是文件,那么调用getSingleFileMD5 计算命令行参数里面所有文件的MD5值
16. if
17. $arg = $ARGV[0];
18. if (-d $arg
19. if ($ARGV[1] eq '-f' && -T $ARGV[2]){
20. $arg);
21. else
22. &getDirectoryAllFileMD5(@ARGV);
23. }
24. $arg
25. &getSingleFileMD5(@ARGV);
26. $arg eq '-c'
27. die "$usagecompare\n" unless (-T $ARGV[1] && -T $ARGV[2]);
28. &compareWithTwoMD5Files;
29. $arg eq '-p') {
30. if
31. &getPathBinFileMD5;
32. $ARGV[1] eq '-f' && -T $ARGV[2]) {
33. &compareWithLastPathMD5File;
34. else
35. die "$usagepath\n";
36. }
37. else
38. die "$usage\n";
39. }
40. } else
41. die "$usage\n";
42. }
43.
44. #得到目录下所有文件(包括子目录)的MD5值
45. sub getDirectoryAllFileMD5 {
46. find(\&wantedPrint,@_);
47. }
48.
49. #得到PATH变量里面所有的二进制文件的MD5值
50. sub getPathBinFileMD5 {
51. $ENV{PATH};
52. find(\&wantedPrint,@path);
53. }
54.
55. #先得到本次PATH变量所有的目录下的文件的MD5值,然后对比以前是生成的MD5文件
56. sub compareWithLastPathMD5File {
57. $ENV{PATH};
58. &compareWithLastMD5File(@path);
59. }
60.
61. #得到单个文件的MD5值
62. sub getSingleFileMD5 {
63. foreach
64. if (-R $_) {
65. "$_ ",&getMD5($_),"\n";
66. else
67. "Can't read $_\n";
68. next;
69. }
70. }
71. }
72.
73. #先生成该目录下所有文件的MD5值,然后跟上一次该目录的生成的MD5文件对比
74. #本次生成的MD5跟上一次生成的MD5文件比对,不一致的输出出来,同时将3个时间输出出来
75. #如果是新添加的文件则输出出来其3个时间值,atime mtime ctime
76. sub compareWithLastMD5File {
77. find(\&wantedHash,@_); #这里调用那个回调函数后就会生成一个%thisMD5Hash的哈希
78. $md5file = $ARGV[2];
79.
80. "<","$md5file" or die "Can't read $md5file : $!\n";
81. $lastMD5Filerecords
82. %lastMD5Hash = map { split } @lastMD5FilerecordsArray;
83. close LASTMD5FILE;
84.
85. foreach
86. $thisMD5Filerecords++;
87. }
88. $thisMD5Filerecords,$lastMD5Filerecords);
89. }
90.
91. #比较2个生成的MD5文件(对同一个目录生成的),找出不同的或者不存在的
92. sub compareWithTwoMD5Files {
93. $md5file1,$md5file2) = ($ARGV[1],$ARGV[2]);
94. "<","$md5file1" or die "Can't read $md5file1 : $!\n";
95. "<","$md5file2" or die "Can't read $md5file2 : $!\n";
96. $file1record
97. $file2record
98. close MD5FILE1;
99. close MD5FILE2;
100.
101. %thisMD5Hash = map { split } @file1record;
102. %lastMD5Hash = map { split } @file2record;
103. $file1record,$file2record);
104. }
105.
106. #对2个MD5文件进行比较或者是边生成边比对
107. sub compare {
108. $file1record,$file2record) = ($_[0],$_[1]);
109.
110. if ($file1record >= $file2record) {
111. %hash1 = %thisMD5Hash;
112. %hash2 = %lastMD5Hash;
113. else
114. %hash1 = %lastMD5Hash;
115. %hash2 = %thisMD5Hash;
116. }
117.
118. $count
119. foreach
120. if (exists $hash2{$_}) {
121. if ( $hash1{$_} ne $hash2{$_} ) {
122. $count++;
123. $atime,$mtime,$ctime) = &getFileAMCTime($_);
124. "Different --> $_\n";
125. "$hash2{$_}\n";
126. "$hash1{$_} Atime:$atime Mtime:$mtime Ctime:$ctime\n\n";
127. }
128. else
129. $count++;
130. if (-e $_) {
131. $atime,$mtime,$ctime) = &getFileAMCTime($_);
132. "Added --> $_ \n$hash1{$_} Atime:$atime Mtime:$mtime Ctime:$ctime\n\n";
133. else
134. "Deleted --> $_ $hash1{$_}\n\n";
135. }
136. }
137. }
138. if ($count
139. "Not Found Different !!\n";
140. }
141. }
142.
143. #遍历条件,找到之后输出
144. sub wantedPrint {
145. if (-f $_ && -R $_) {
146. "$File::Find::name ",&getMD5($_),"\n";
147. }
148. }
149.
150. #遍历条件,找到之后形成一个HASH
151. sub wantedHash {
152. if (-f $_ && -r $_) {
153. $thisMD5Hash{$File::Find::name} = &getMD5($_);
154. }
155. }
156.
157. #计算MD5值
158. sub getMD5 {
159. $file
160. $file) or die "Can't open '$file': $!\n";
161. binmode(FH);
162. $filemd5 = Digest::MD5->new->addfile(FH)->hexdigest;
163. close FH;
164. return $filemd5;
165. }
166.
167. #获取文件的atime,mtime,ctime
168. sub getFileAMCTime {
169. $filename
170. $atime,$mtime ,$ctime) = (stat ($filename))[8,9,10];
171. $atime = &getTime($atime);
172. $mtime = &getTime($mtime);
173. $ctime = &getTime($ctime);
174.
175. #将日期时间格式转换为比较友好的格式
176. sub getTime {
177. $time
178. $sec,$min,$hour,$day,$mon,$year) = (localtime $time)[0..5];
179. $time = sprintf "%4d-%02d-%02d %2d:%02d:%02d",$year + 1900,$mon + 1,$day,$hour,$min,$sec;
180. return $time;
181. }
182. return $atime,$mtime,$ctime;
183. }
【第一版】
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. '-f'
20. &compareWithLastMD5File($arg);
21. else
22. &getDirectoryAllFileMD5(@ARGV);
23. }
24. } elsif ( -f $arg ) {
25. &getSingleFileMD5(@ARGV);
26. '-c'
27. "$usagecompare\n"
28. &compareWithTwoMD5Files;
29. '-p') {
30. "$usagepath\n"
31. &getPathBinFileMD5;
32. else
33. "$usage\n";
34. }
35. else
36. "$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. "$_ ",&getMD5($_),"\n";
55. else
56. "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
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. "Different:$_ $hash1{$_} Atime:$atime Mtime:$mtime Ctime:$ctime\n";
91. }
92. else
93. if (-e $_) {
94. ($atime,$mtime,$ctime) = &getFileAMCTime($_);
95. "Added:$_ $hash1{$_} Atime:$atime Mtime:$mtime Ctime:$ctime\n";
96. else
97. "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
111. close
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. "Different:$_ $hash1{$_} Atime:$atime Mtime:$mtime Ctime:$ctime\n";
129. }
130. else
131. if (-e $_) {
132. ($atime,$mtime,$ctime) = &getFileAMCTime($_);
133. "Added:$_ $hash1{$_} Atime:$atime Mtime:$mtime Ctime:$ctime\n";
134. else
135. "Deleted:$_ $hash1{$_}\n";
136. }
137. }
138. }
139. }
140.
141. #遍历条件,找到之后输出
142. sub wantedPrint {
143. if (-f $_ && -R $_) {
144. "$File::Find::name ",&getMD5($_),"\n";
145. }
146. }
147.
148. #遍历条件,找到之后形成一个HASH
149. sub wantedHash {
150. if (-f $_ && -r $_) {
151. 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
162. return
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. time
176. 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
181. }
转载于:https://blog.51cto.com/linux5588/1070915