比较 bash 脚本中的 md5 总和

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33049634/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 13:42:16  来源:igfitidea点击:

Compare md5 sums in bash script

linuxbashshell

提问by Keiro

I'm trying to use md5sumto compare two files in a bashscript.

我正在尝试用于md5sum比较bash脚本中的两个文件。

The goal is to use the .md5of one file to check the md5sumof 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.

目标是使用.md5一个文件的 来检查md5sum另一个文件的 。我的谷歌搜索如何正确地做到这一点并没有向我展示我是如何做到这一点的。发送电子邮件的工作正如您所期望的那样。现在我试图让它在失败而不是成功时发送电子邮件。

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.

并且可能列出从 .md5 文件收到的结果和损坏文件的实际 md5sum。我最终会解决这个问题,但这有点令人困惑,因为我试图找出我在这里出错的地方。

Shellcheck indicates that the code looks good, but I'm not getting the results that I'm expecting to get.

Shellcheck 表明代码看起来不错,但我没有得到我期望得到的结果。

A few StackOverflow links that I checked out to see if something could be worked:

我检查了一些 StackOverflow 链接,看看是否可以工作:

One

Two

Here's the content of my bash script, in its original form:

这是我的 bash 脚本的原始内容:

#!/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:

Edit2:代码现在如下,另外,请注意我删除了 GeoLiteCity2 和 GeoLite,这样我们每次 MaxMind 更新他们的数据库时都会重新下载数据库:

#!/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

采纳答案by ghoti

So .. the problem you're seeing appears to be that the format of the md5sum.txtfile you create doesn't match the format of the .md5file that you download, against which you need to check the value that you calculate.

所以..您看到的问题似乎是md5sum.txt您创建的.md5文件格式与您下载的文件格式不匹配,您需要根据该格式检查您计算的值。

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.datinstead of -rf. Let's not reach farther than we need to.
  • md5sumtakes 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 md5sumcommand, this still doesn't match the .md5 file you download from Maxmind, so:
  • cutis used to modify the resultant output, leaving only the calculated md5.
  • using cmpinstead of subshells, per comments on your question.
  • rm -f GeoLightCity.dat而不是-rf. 让我们不要超出我们需要的范围。
  • md5sum接受标准输入而不是按名称处理文件。结果是输出不包含文件名。不幸的是,由于 Linuxmd5sum命令的限制,这仍然与您从 Maxmind 下载的 .md5 文件不匹配,因此:
  • cut用于修改结果输出,只留下计算出的 md5。
  • cmp根据对您的问题的评论,使用而不是子外壳。

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:

创建 md5sum.txt 文件的另一个选择是在下载时即时进行。例如:

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 teecommand to split the file into its "save" location and another pipe, which goes through md5sum to generate your .txt file.

这使用tee命令将文件拆分为其“保存”位置和另一个管道,该管道通过 md5sum 生成您的 .txt 文件。

Might save you a minute that would otherwise be eaten by the md5sum that runs afterwards. And it'll take better advantage of SMP. :)

可能会为您节省一分钟,否则会被随后运行的 md5sum 吃掉。它将更好地利用 SMP。:)

回答by Jsilvermist

For anyone coming here looking to compare a file to a specific md5 sum, you can try this function:

对于来这里希望将文件与特定 md5 总和进行比较的任何人,您可以尝试此功能:

function checkmd5() {
  md5_to_test=
  md5_from_file=$(md5sum "" | 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

回答by Samuel

In that line if [ $file1 != $file2 ], you're not comparing content of two files, but file names only. So if [ "md5sum.txt" != "GeoLite2-City.md5" ]will be always true.

在该行中if [ $file1 != $file2 ],您不是在比较两个文件的内容,而是仅比较文件名。所以if [ "md5sum.txt" != "GeoLite2-City.md5" ]永远都是真的。

That should work:

那应该工作:

if [ "`awk '{print ;}' $file1`" != "`cat $file2`" ]; then
...do your logic here...
fi