当文件修改时更新 md5 校验和

当文件修改时更新 md5 校验和

我有一个服务器,当特定文件夹的内容被修改时,它会计算校验和。

问题在于,校验和的计算需要大约 30 分钟,因为即使修改了一个简单的文本文件,它也会重新计算该文件夹中的每个文件。因此,在运行校验和时,这些文件将无法使用。

校验和的计算是通过以下命令完成的。

find . -type f | xargs md5sum > some_file

每天都会有新文件添加到该文件夹​​中,同时也会删除其他文件。

有没有办法仅在修改/添加/删除的文件上更新校验和文件,而无需计算其余文件的 md5?

编辑:澄清

校验和需要包含该文件夹中每个文件的 md5。我试图实现的是一种当文件夹中发生更改时编辑/更新校验和文件的方法:

  1. 删除文件时删除其 md5
  2. 在文件夹中添加文件时添加 md5
  3. 当文件修改时更新哈希码

所有这些都不需要从顶部重新计算整个文件夹

答案1

这是一个非常粗糙的脚本,试图做你想做的事情。请随意复制、修改、优化 - 如果它对你有用,那就太好了。我在我的“下载”文件夹中测试过,只发现一个错误(文件名包含[,我grep不喜欢)。

编辑:再次修改了源代码,因为使用 可以找到新的/修改过的文件,因此不再需要创建时间戳(在第一个版本中)find -newer。还添加了参数来设置哈希文件的名称以及可能要从其开始的顶级文件夹;因此不必从顶级目录调用脚本。

#!/bin/bash
#
# Script to create md5 hashes for files in and below the current directory
# or the directory passed at the commandline
# In the first run, create the sums for all files.
# In the second run,
#  - if the files have not changed, keep the entries
#  - if the files have been deleted, forget the entry
#  - if the files have changed, create new md5 hash.
#
# Rough version - should be optimized
#

if [ $# -lt 1 ] ; then
  echo "Usage:"
  echo "$0 <hashfile> [<topdir>]"
  echo
  exit
fi

export HASHFILE=$1
export TOPDIR='.'
if [ $# -eq 2 ] ; then TOPDIR=$2; fi

export BACKFILE=$HASHFILE.bck
export TMPFILE=$HASHFILE.tmp

# In the first run, we create the file $HASHFILE if it does not exist
# You have to make sure that $HASHFILE does not contain any garbage for the first run!!

if [ ! \( -f $HASHFILE -a -s $HASHFILE \) ]; then
  echo -n "Creating $HASHFILE for the first time..."
  find $TOPDIR -type f -print0 | xargs -0 md5sum > $HASHFILE
  echo "done."
  exit
fi

# In the second run, we proceed to find the differences.
# First, find the newer files

find $TOPDIR -type f -newer $HASHFILE -print > $TMPFILE

# Now save the old file and create a new one, starting with new files

mv $HASHFILE $BACKFILE
echo -n "Processing new or modified files ..."
cat $TMPFILE | while read filename ; do
  md5sum "$filename" >> $HASHFILE
done
echo "done."

# Now walk through the old file and process to new file

cat $BACKFILE | while read md5 filename ; do
  # Does the file still exist?
  if [ -f "$filename" ] ; then
    # Has the file been modified?
    if grep -q -e "^$filename$" $TMPFILE ; then 
      echo "$filename has changed!"
    else
      echo "$md5  $filename" >> $HASHFILE
      #echo "$filename has not changed."
    fi
  else
    echo "$filename has been removed!"
  fi
done

# We now may delete temporary files
# rm $BACKFILE
# rm $TMPFILE

exit

答案2

我编写了一个名为 RDChecksum 的脚本,它能够根据“上次修改”时间戳更新文件校验和:

https://github.com/rdiez/Tools/tree/master/RDChecksum

相关内容