Script Function
The script is written in Perl to calculate the MD5 value of the file.
Script usage
After installing the operating system, the server calculates the MD5 values of all the binary files in the PATH variable, calculates the MD5 values of a single file, and computes a directory (including subdirectories) the MD5 values of all files are recorded in the file, and a new copy is generated later. Then, two files are compared to determine whether these files have been modified.
Script usage (6 usage)
Script Name-p [> output file name] annotate this function is used to calculate the MD5 value of all files in the PATH variable
Script Name-p-f MD5 file [> output file name]. This function calculates the MD5 value of all files in the PATH variable and keeps up with the generated MD5 file.
Script Name file 1 file 2 file 3... [> output file name] compute this function is used to calculate the MD5 value of a specified file
Script Name directory 1 directory 2 Directory 3... [> output file name] compute this function is used to calculate the MD5 value of all files in a specified directory
Script Name-c MD5 file 1 MD5 file 2 [> output file name]. This function compares the MD5 values of all files in the same directory that are generated twice.
Script Name directory-f MD5 file [> output file name]. This function is similar to the preceding function, but this function is used for direct comparison without generating files.
Notes
Cannot calculate the/proc directory
The/(Root) cannot be calculated because/contains/proc
You cannot calculate the shared directory mounted to Windows on Linux.
Script content
[Version 2]
#! /Usr/bin/perl
Use Digest: MD5;
Use File: Find;
#2012-12-16 Leo chanyipiaomiao@163.com
# Blog: http://linux5588.blog.51cto.com
# Usage tips
$ Usage = "Usage: scriptname-p | Directory1... | File1... |-c MD5File1 MD5File2 | Directory-f MD5File [> OUTFILE]";
$ Usagecompare = "Usage: scriptname-c MD5File1 MD5File2 [> OUTFILE]";
$ Usagepath = "Usage: scriptname-p |-p-f MD5File [> OUTFILE]";
# Determine whether the command line parameter is null. If it is null, the MD5 value of all the binary files in the PATH is calculated directly.
# If the first parameter is a directory, call getDirectoryAllFileMD5 to calculate the MD5 value of all files in the directory.
# If the first parameter is a file, call getSingleFileMD5 to calculate the MD5 value of all files in the command line parameter
If (@ ARGV ){
My $ arg = $ ARGV [0];
If (-d $ arg ){
If ($ ARGV [1] eq '-F' &-T $ ARGV [2]) {
& CompareWithLastMD5File ($ arg );
} Else {
& GetDirectoryAllFileMD5 (@ ARGV );
}
} Elsif (-f $ arg ){
& GetSingleFileMD5 (@ ARGV );
} Elsif ($ arg eq '-C' & @ ARGV = 3 ){
Die "$ usagecompare \ n" unless (-T $ ARGV [1] &-T $ ARGV [2]);
& CompareWithTwoMD5Files;
} Elsif ($ arg eq '-p '){
If (1 = @ ARGV ){
& GetPathBinFileMD5;
} Elsif ($ ARGV [1] eq '-F' &-T $ ARGV [2]) {
& CompareWithLastPathMD5File;
} Else {
Die "$ usagepath \ n ";
}
} Else {
Die "$ usage \ n ";
}
} Else {
Die "$ usage \ n ";
}
# Obtain the MD5 value of all files (including subdirectories) in the directory
Sub getDirectoryAllFileMD5 {
Find (\ & wantedPrint ,@_);
}
# Obtain the MD5 value of all the binary files in the PATH variable.
Sub getPathBinFileMD5 {
My @ path = split/:/, $ ENV {PATH };
Find (\ & wantedPrint, @ path );
}
# First obtain the MD5 value of the files in all directories of the PATH variable, and then compare it with the previously generated MD5 File
Sub compareWithLastPathMD5File {
My @ path = split/:/, $ ENV {PATH };
& CompareWithLastMD5File (@ path );
}
# Obtain the MD5 value of a single file
Sub getSingleFileMD5 {
Foreach (@_){
If (-R $ _){
Print "$ _", & getMD5 ($ _), "\ n ";
} Else {
Print "Can't read $ _ \ n ";
Next;
}
}
}
# Convert the MD5 values of all files in this directory and compare them with the MD5 files generated in this directory.
# The generated MD5 file is compared with the generated MD5 file. The generated MD5 file is output in different ways at the same time.
# If it is a newly added file, three time values are output, atime mtime ctime
Sub compareWithLastMD5File {
Find (\ & wantedHash, @ _); # after calling the callback function, a hash of % thisMD5Hash is generated.
My $ md5file = $ ARGV [2];
Open LASTMD5FILE, "<", "$ md5file" ordie "Can't read $ md5file: $! \ N ";
My $ lastMD5Filerecords = (@ lastMD5FilerecordsArray = <LASTMD5FILE> );
% LastMD5Hash = map {split} @ lastMD5FilerecordsArray;
Close LASTMD5FILE;
Foreach (keys % thisMD5Hash ){
$ ThisMD5Filerecords ++;
}
& Compare ($ thisMD5Filerecords, $ lastMD5Filerecords );
}
# Compare two generated MD5 files (generated for the same directory) to find different or nonexistent
Sub compareWithTwoMD5Files {
My ($ md5file1, $ md5file2) = ($ ARGV [1], $ ARGV [2]);
Open MD5FILE1, "<", "$ md5file1" ordie "Can't read $ md5file1: $! \ N ";
Open MD5FILE2, "<", "$ md5file2" ordie "Can't read $ md5file2: $! \ N ";
My $ file1record = (@ file1record = <MD5FILE1> );
My $ file2record = (@ file2record = <MD5FILE2> );
Close MD5FILE1;
Close MD5FILE2;
% ThisMD5Hash = map {split} @ file1record;
% LastMD5Hash = map {split} @ file2record;
& Compare ($ file1record, $ file2record );
}
# Compare two MD5 files or generate edge comparison
Sub compare {
My ($ file1record, $ file2record) = ($ _ [0], $ _ [1]);
If ($ file1record >=$ file2record ){
% Hash1 = % thisMD5Hash;
% Hash2 = % lastMD5Hash;
} Else {
% Hash1 = % lastMD5Hash;
% Hash2 = % thisMD5Hash;
}
My $ count = 0;
Foreach (keys % hash1 ){
If (exists $ hash2 {$ _}){
If ($ hash1 {$ _} ne $ hash2 {$ _}){
$ Count ++;
($ Atime, $ mtime, $ ctime) = & getFileAMCTime ($ _);
Print "Different --> $ _ \ n ";
Print "$ hash2 {$ _} \ n ";
Print "$ hash1 {$ _} Atime: $ atime Mtime: $ mtime Ctime: $ ctime \ n ";
}
} Else {
$ Count ++;
If (-e $ _){
($ Atime, $ mtime, $ ctime) = & getFileAMCTime ($ _);
Print "Added --> $ _ \ n $ hash1 {$ _} Atime: $ atime Mtime: $ mtime Ctime: $ ctime \ n ";
} Else {
Print "Deleted --> $ _ $ hash1 {$ _} \ n ";
}
}
}
If ($ count = 0 ){
Print "Not Found Different !! \ N ";
}
}
# Traverse the condition and output it after finding it
Sub wantedPrint {
If (-f $ _ &-R $ _){
Print "$ File: Find: name", & getMD5 ($ _), "\ n ";
}
}
# Traverse condition. After finding the condition, a HASH is formed.
Sub wantedHash {
If (-f $ _ &-r $ _){
$ ThisMD5Hash {$ File: Find: name} = & getMD5 ($ _);
}
}
# Calculate the MD5 Value
Sub getMD5 {
My $ file = shift @_;
Open (FH, $ file) ordie "Can't open '$ file': $! \ N ";
Binmode (FH );
My $ filemd5 = Digest: MD5-> new-> addfile (FH)-> hexdigest;
Close FH;
Return $ filemd5;
}
# Obtain the atime, mtime, and ctime of a file
Sub getFileAMCTime {
$ Filename = shift @_;
My ($ atime, $ mtime, $ ctime) = (stat ($ filename) [8, 9, 10];
$ Atime = & getTime ($ atime );
$ Mtime = & getTime ($ mtime );
$ Ctime = & getTime ($ ctime );
# Convert the date and time format to a friendly format
Sub getTime {
My $ time = shift @_;
My ($ sec, $ min, $ hour, $ day, $ mon, $ year) = (localtime $ time) [0 .. 5];
$ Time = sprintf "% 4d-% 02d-% 02d % 2d: % 02d: % 02d", $ year + 1900, $ mon + 1, $ day, $ hour, $ min, $ sec;
Return $ time;
}
Return $ atime, $ mtime, $ ctime;
}
[First version]
#! /Usr/bin/perl
Use Digest: MD5;
Use File: Find;
#2012-11-24 Leo chanyipiaomiao@163.com
# Blog: http://linux5588.blog.51cto.com
# Usage tips
$ Usage = "Usage: scriptname-p | Directory1... | File1... |-c MD5File1 MD5File2 | Directory-f MD5File [> OUTFILE]";
$ Usagecompare = "Usage: scriptname-c MD5File1 MD5File2 [> OUTFILE]";
$ Usagepath = "Usage: scriptname-p [> OUTFILE]";
# Determine whether the command line parameter is null. If it is null, the MD5 value of all the binary files in the PATH is calculated directly.
# If the first parameter is a directory, call getDirectoryAllFileMD5 to calculate the MD5 value of all files in the directory.
# If the first parameter is a file, call getSingleFileMD5 to calculate the MD5 value of all files in the command line parameter
If (@ ARGV ){
My $ arg = $ ARGV [0];
If (-d $ arg ){
If ($ ARGV [1] eq '-F' &-T $ ARGV [2]) {
& CompareWithLastMD5File ($ arg );
} Else {
& GetDirectoryAllFileMD5 (@ ARGV );
}
} Elsif (-f $ arg ){
& GetSingleFileMD5 (@ ARGV );
} Elsif ($ arg eq '-C' & @ ARGV = 3 ){
Die "$ usagecompare \ n" unless (-T $ ARGV [1] &-T $ ARGV [2]);
& CompareWithTwoMD5Files;
} Elsif ($ arg eq '-p '){
Die "$ usagepath \ n" unless (@ ARGV = 1 );
& GetPathBinFileMD5;
} Else {
Die "$ usage \ n ";
}
} Else {
Die "$ usage \ n ";
}
# Obtain the MD5 value of all files (including subdirectories) in the directory
Sub getDirectoryAllFileMD5 {
Find (\ & wantedPrint ,@_);
}
# Obtain the MD5 value of all the binary files in the PATH variable.
Sub getPathBinFileMD5 {
My @ path = split/:/, $ ENV {PATH };
Find (\ & wantedPrint, @ path );
}
# Obtain the MD5 value of a single file
Sub getSingleFileMD5 {
Foreach (@_){
If (-R $ _){
Print "$ _", & getMD5 ($ _), "\ n ";
} Else {
Print "Can't read $ _ \ n ";
Next;
}
}
}
# Convert the MD5 values of all files in this directory and compare them with the MD5 files generated in this directory.
# The generated MD5 file is compared with the generated MD5 file. The generated MD5 file is output in different ways at the same time.
# If it is a newly added file, three time values are output, atime mtime ctime
Sub compareWithLastMD5File {
Find (\ & wantedHash ,@_);
My $ md5file = $ ARGV [2];
Open MD5FILE, "<", "$ md5file" or die "Can't read $ md5file: $! \ N ";
My $ lastMD5Filerecords = (@ lastMD5FilerecordsArray = <MD5FILE> );
My % lastMD5Hash = map {split} @ lastMD5FilerecordsArray;
Close MD5FILE;
Foreach (keys % thisMD5Hash ){
$ ThisMD5Filerecords ++;
}
If ($ thisMD5Filerecords >=$ lastMD5Filerecords ){
% Hash1 = % thisMD5Hash;
% Hash2 = % lastMD5Hash;
} Else {
% Hash1 = % lastMD5Hash;
% Hash2 = % thisMD5Hash;
}
Foreach (keys % hash1 ){
If (exists $ hash2 {$ _}){
If ($ hash1 {$ _} ne $ hash2 {$ _}){
($ Atime, $ mtime, $ ctime) = & getFileAMCTime ($ _);
Print "Different: $ _ $ hash1 {$ _} Atime: $ atime Mtime: $ mtime Ctime: $ ctime \ n ";
}
} Else {
If (-e $ _){
($ Atime, $ mtime, $ ctime) = & getFileAMCTime ($ _);
Print "Added: $ _ $ hash1 {$ _} Atime: $ atime Mtime: $ mtime Ctime: $ ctime \ n ";
} Else {
Print "Deleted: $ _ $ hash1 {$ _} \ n ";
}
}
}
}
# Compare two generated MD5 files (generated for the same directory) to find different or nonexistent
Sub compareWithTwoMD5Files {
My ($ md5file1, $ md5file2) = ($ ARGV [1], $ ARGV [2]);
Open MD5FILE1, "<", "$ md5file1" or die "Can't read $ md5file1: $! \ N ";
Open MD5FILE2, "<", "$ md5file2" or die "Can't read $ md5file2: $! \ N ";
My $ file1record = (@ file1record = <MD5FILE1> );
My $ file2record = (@ file2record = <MD5FILE2> );
Close MD5FILE1;
Close MD5FILE2;
My % hashmap1 = map {split} @ file1record;
My % hashmap2 = map {split} @ file2record;
If ($ file1record >=$ file2record ){
% Hash1 = % hashmap1;
% Hash2 = % hashmap2;
} Else {
% Hash1 = % hashmap2;
% Hash2 = % hashmap1;
}
Foreach (keys % hash1 ){
If (exists $ hash2 {$ _}){
If ($ hash1 {$ _} ne $ hash2 {$ _}){
($ Atime, $ mtime, $ ctime) = & getFileAMCTime ($ _);
Print "Different: $ _ $ hash1 {$ _} Atime: $ atime Mtime: $ mtime Ctime: $ ctime \ n ";
}
} Else {
If (-e $ _){
($ Atime, $ mtime, $ ctime) = & getFileAMCTime ($ _);
Print "Added: $ _ $ hash1 {$ _} Atime: $ atime Mtime: $ mtime Ctime: $ ctime \ n ";
} Else {
Print "Deleted: $ _ $ hash1 {$ _} \ n ";
}
}
}
}
# Traverse the condition and output it after finding it
Sub wantedPrint {
If (-f $ _ &-R $ _){
Print "$ File: Find: name", & getMD5 ($ _), "\ n ";
}
}
# Traverse condition. After finding the condition, a HASH is formed.
Sub wantedHash {
If (-f $ _ &-r $ _){
$ ThisMD5Hash {$ File: Find: name} = & getMD5 ($ _);
}
}
# Calculate the MD5 Value
Sub getMD5 {
My $ file = shift @_;
Open (FH, $ file) or die "Can't open '$ file': $! \ N ";
Binmode (FH );
My $ filemd5 = Digest: MD5-> new-> addfile (FH)-> hexdigest;
Close FH;
Return $ filemd5;
}
# Obtain the atime, mtime, and ctime of a file
Sub getFileAMCTime {
$ Filename = shift @_;
My ($ atime, $ mtime, $ ctime) = (stat ($ filename) [8, 9, 10];
$ Atime = & getTime ($ atime );
$ Mtime = & getTime ($ mtime );
$ Ctime = & getTime ($ ctime );
# Convert the date and time format to a friendly format
Sub getTime {
My $ time = shift @_;
My ($ sec, $ min, $ hour, $ day, $ mon, $ year) = (localtime $ time) [0 .. 5];
$ Time = sprintf "% 4d-% 02d-% 02d % 2d: % 02d: % 02d", $ year + 1900, $ mon + 1, $ day, $ hour, $ min, $ sec;
Return $ time;
}
Return $ atime, $ mtime, $ ctime;
}
This article is from the blog of reelcos, please be sure to keep this source http://linux5588.blog.51cto.com/65280/1070915