I'm trying to use md5sum
to compare two files in a bash
script.
The goal is to use the .md5
of one file to check the md5sum
of the other file. My Google searches on how to do this the proper way isn't showing me how I'm doing this. Firing off an e-mail works as you'd expect. Now I'm trying to get it to fire off an e-mail on failure rather than success.
And maybe list the result of what was received from the .md5 file and the actual md5sum of the corrupted file. I'll figure this out, eventually but this is somewhat confusing since I have tried to figure out where I'm going wrong here.
Shellcheck indicates that the code looks good, but I'm not getting the results that I'm expecting to get.
A few StackOverflow links that I checked out to see if something could be worked:
One
Two
Here's the content of my bash script, in its original form:
#!/bin/bash
cd /home/example/public_html/exampledomain.com/billing/system/ || exit
rm -rf GeoLiteCity.dat
curl -L https://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz | gunzip > GeoLiteCity.dat
curl -L https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz | gunzip > GeoLite2-City.dat
curl -L https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.md5
md5sum GeoLite2-City.dat > md5sum.txt
file1="md5sum.txt"
file2="GeoLite2-City.md5"
if [ "`cat $file1`" != "`cat $file2`" ]; then
mail -s "Results of GeoLite Updates" [email protected] <<< "md5sum for GeoLite2-City failed. Please check the md5sum. File may possibly be corrupted."
else
exit
fi
Edit:
Updated the code to the following:
#!/bin/bash
cd /home/example/web/exampledomain/public_html/billing/system/ || exit
rm -rf GeoLite*
rm -rf md5sum.txt
curl -L https://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz | gunzip > GeoLiteCity.dat
curl -L https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz | gunzip > GeoLite2-City.dat
wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.md5
md5sum GeoLite2-City.dat > md5sum.txt
file1="md5sum.txt"
file2="GeoLite2-City.md5"
if ! cmp "$file1" "$file2"; then echo "They don't match."; fi
Still working on this. Getting closer to actually making it work!
Results of the above:
root@example# cat GeoLite2-City.md5
e8c076d6ff83e9a615aedc7d5d1842d7
root@example# md5sum GeoLite2-City.dat
e8c076d6ff83e9a615aedc7d5d1842d7 GeoLite2-City.dat
root@example# cat md5sum.txt
e8c076d6ff83e9a615aedc7d5d1842d7 GeoLite2-City.dat
Edit2: Code is now as follows, also, note that I remove GeoLiteCity2 and GeoLite so that we start with a fresh download of the databases every time MaxMind updates their database:
#!/bin/bash
# cd to directory where the MaxMind database is to be downloaded.
if ! cd /home/example/public_html/billing/system/; then
echo "Can't find work directory" >&2
exit 1
fi
# Remove existing files so we start off with a clean set of updated data from Maxmind.
rm -f GeoLite*
rm -f md5sum.txt
# Download databases and if applicable, their md5s.
curl -L https://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz | gunzip > GeoLiteCity.dat
curl -L https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz | gunzip > GeoLite2-City.dat
curl -O https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.md5
# Create md5sum of the GeoLite2 database.
md5sum < GeoLite2-City.dat > md5sum.txt
# Strip out the spurious - seen in md5sum.txt
sed -i 's/ .*//' md5sum.txt
# Set what files are what for file comparison purposes.
file1="md5sum.txt"
file2="GeoLite2-City.md5"
# DO THE THING! ie, compare!
if ! cmp --silent "$file1" "$file2"; then
mail -s "Results of GeoLite Updates" [email protected] <<< "md5sum for GeoLite2-City failed. Please check the md5sum. File may possibly be corrupted."
fi
Comparison operators are operators that compare values and return true or false. When comparing strings in Bash you can use the following operators: string1 = string2 and string1 == string2 - The equality operator returns true if the operands are equal. Use the = operator with the test [ command.
To compare files in Linux and even in macOS, a utility used is called the “diff”. The “diff” utility compares two files and gives information about the differences between the two files. The developers primarily use the “diff” command to create patch files.
So .. the problem you're seeing appears to be that the format of the md5sum.txt
file you create doesn't match the format of the .md5
file that you download, against which you need to check the value that you calculate.
The following would be closer to my version of the script. (Explanation below.)
#!/bin/bash
if ! cd /home/example/public_html/exampledomain.com/billing/system/; then
echo "Can't find work directory" >&2
exit 1
fi
rm -f GeoLiteCity.dat
curl -L https://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz | gunzip > GeoLiteCity.dat
curl -L https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz | gunzip > GeoLite2-City.dat
curl -O https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.md5
md5sum < GeoLite2-City.dat | cut -d\ -f1 > md5sum.txt
file1="md5sum.txt"
file2="GeoLite2-City.md5"
if ! cmp --silent "$file1" "$file2"; then
mail -s "Results of GeoLite Updates" [email protected] <<< "md5sum for GeoLite2-City failed. Please check the md5sum. File may possibly be corrupted."
fi
The major differences here are..
rm -f GeoLightCity.dat
instead of -rf
. Let's not reach farther than we need to.md5sum
takes standard input rather than processing the file by name. The effect is that the output does not include a filename. Unfortunately because of limitations to the Linux md5sum
command, this still doesn't match the .md5 file you download from Maxmind, so:cut
is used to modify the resultant output, leaving only the calculated md5.cmp
instead of subshells, per comments on your question.The second and third points are perhaps the most important ones for you.
Another option for creating your md5sum.txt file would be to do it on-the-fly as you're download. For example:
curl -L https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz \
| gunzip | tee -a GeoLite2-City.dat | cut -d\ -f1 | md5sum > md5sum.txt
This uses the tee
command to split the file into its "save" location and another pipe, which goes through md5sum to generate your .txt file.
Might save you a minute that would otherwise be eaten by the md5sum that runs afterwards. And it'll take better advantage of SMP. :)
For anyone coming here looking to compare a file to a specific md5 sum, you can try this function:
function checkmd5() {
md5_to_test=$1
md5_from_file=$(md5sum "$2" | cut -d " " -f1)
md5_results="Input: $md5_to_test\nFile: $md5_from_file"
if [[ $md5_to_test == $md5_from_file ]]
then
echo -e "\n\e[92mSUCCESS\e[39m\n$md5_results"
else
echo -e "\n\e[91mFAILURE\e[39m\n$md5_results"
fi
}
And then just use it like:
$ checkmd5 <SOME_MD5_SUM> filepath/file.abc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With