Linux 如何计算目录的md5校验和?

Linux 如何计算目录的md5校验和?,linux,directory,md5sum,Linux,Directory,Md5sum,我需要为一个目录和所有子目录下的所有特定类型的文件(例如,*.py)计算一个汇总md5校验和 2bcf49a4d19ef9abd284311108d626f1 - 最好的方法是什么 编辑:建议的解决方案非常好,但这并不是我所需要的。我正在寻找一种解决方案,以获得一个单一摘要校验和,该校验和将唯一地标识整个目录,包括其所有子目录的内容。如果您希望一个md5sum跨越整个目录,我将执行以下操作 cat *.py | md5sum 2bcf49a4d19ef9abd284311108d626f

我需要为一个目录和所有子目录下的所有特定类型的文件(例如,
*.py
)计算一个汇总md5校验和

2bcf49a4d19ef9abd284311108d626f1  -
最好的方法是什么


编辑:建议的解决方案非常好,但这并不是我所需要的。我正在寻找一种解决方案,以获得一个单一摘要校验和,该校验和将唯一地标识整个目录,包括其所有子目录的内容。

如果您希望一个md5sum跨越整个目录,我将执行以下操作

cat *.py | md5sum 
2bcf49a4d19ef9abd284311108d626f1  -
GNU查找

find /path -type f -name "*.py" -exec md5sum "{}" +;

动态创建一个tar归档文件,并将其传送到
md5sum

tar c dir | md5sum
这将生成一个md5sum,该md5sum对于文件和子目录设置来说应该是唯一的。磁盘上没有创建任何文件

find /path/to/dir/ -type f -name "*.py" -exec md5sum {} + | awk '{print $1}' | sort | md5sum
find命令列出以.py结尾的所有文件。 将为每个.py文件计算md5sum。awk用于提取md5sums(忽略可能不唯一的文件名)。 MD5总和已排序。 然后返回该排序列表的md5sum

我已通过复制测试目录对此进行了测试:

rsync -a ~/pybin/ ~/pybin2/
我重命名了~/pybin2中的一些文件

find…md5sum
命令为两个目录返回相同的输出

2bcf49a4d19ef9abd284311108d626f1  -

从技术上讲,您只需要运行
ls-lR*.py | md5sum
。除非您担心有人修改文件并将其恢复到原始日期,并且从不更改文件大小,否则
ls
的输出应该会告诉您文件是否已更改。我的unix foo很弱,因此您可能需要更多的命令行参数来获得打印的创建时间和修改时间
ls
还会告诉您文件的权限是否已更改(如果您不在乎,我相信会有开关关闭该选项)。

ire\u and\u curses使用
tar c
的建议存在一些问题:

  • tar按照目录条目在文件系统中的存储顺序来处理它们,并且没有办法改变这个顺序。如果您在不同的地方有“相同”的目录,那么这实际上会产生完全不同的结果,我不知道如何解决这个问题(tar无法按特定顺序“排序”其输入文件)
  • 我通常关心的是groupid和ownerid号是否相同,而不一定是group/owner的字符串表示形式是否相同。这与例如rsync-a--delete所做的事情是一致的:它几乎同步所有东西(减去xattrs和acl),但它将根据所有者和组的ID而不是字符串表示同步它们。因此,如果您同步到一个不一定具有相同用户/组的不同系统,您应该将
    --numeric owner
    标志添加到tar
  • tar将包括您正在检查的目录的文件名,这只是需要注意的事项
只要第一个问题没有解决方案(或者除非您确定它不会影响您),我就不会使用这种方法

上面提出的基于
find
的解决方案也不好,因为它们只包含文件,而不包含目录,如果校验和应该记住空目录,这将成为一个问题

2bcf49a4d19ef9abd284311108d626f1  -
最后,大多数建议的解决方案排序不一致,因为不同系统的排序规则可能不同

这就是我提出的解决方案:

dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum

幸运的是,我没有名称中有换行符的文件/目录,因此这在该系统上不是问题。

为了完整起见,有;由于*.py筛选器要求,它不直接适用,但应该与find(1)一起使用。

我也有同样的问题,所以我提出了这个脚本,它只列出目录中文件的MD5和,如果它找到子目录,它将从那里再次运行,要实现这一点,脚本必须能够在当前目录中运行,或者如果在$1中传递了所述参数,则脚本必须能够从子目录中运行

#!/bin/bash

if [ -z "$1" ] ; then

# loop in current dir
ls | while read line; do
  ecriv=`pwd`"/"$line
if [ -f $ecriv ] ; then
    md5sum "$ecriv"
elif [ -d $ecriv ] ; then
    sh myScript "$line" # call this script again
fi

done


else # if a directory is specified in argument $1

ls "$1" | while read line; do
  ecriv=`pwd`"/$1/"$line

if [ -f $ecriv ] ; then
    md5sum "$ecriv"

elif [ -d $ecriv ] ; then
    sh myScript "$line"
fi

done


fi

如果您只关心文件,而不关心空目录,那么这会很好地工作:

find /path -type f | sort -u | xargs cat | md5sum

如果您想真正独立于文件系统属性和某些tar版本的位级别差异,可以使用cpio:

cpio -i -e theDirname | md5sum

使用
md5deep


md5deep-r文件夹| awk'{print$1}'| sort | md5sum

检查所有文件,包括内容及其文件名

grep -ar -e . /your/dir | md5sum | cut -c-32
同上,但仅包括*.py文件

grep -ar -e . --include="*.py" /your/dir | md5sum | cut -c-32
如果需要,也可以使用符号链接

grep -aR -e . /your/dir | md5sum | cut -c-32
<>您可以考虑使用GRP

其他选项
-s, --no-messages         suppress error messages
-D, --devices=ACTION      how to handle devices, FIFOs and sockets;
-Z, --null                print 0 byte after FILE name
-U, --binary              do not strip CR characters at EOL (MSDOS/Windows)

一个最适合我的解决方案:

find "$path" -type f -print0 | sort -z | xargs -r0 md5sum | md5sum
它对我最有效的原因:

find "$path" -type f -print0 | sort -z | xargs -r0 md5sum | md5sum
  • 处理包含空格的文件名
  • 忽略文件系统元数据
  • 检测文件是否已重命名
  • 其他答案的问题:

    对于以下情况,不会忽略文件系统元数据:

    tarc-“$path”| md5sum

    不处理包含空格的文件名,也不检测文件是否已重命名:

    find /path -type f | sort -u | xargs cat | md5sum
    

    还有两种解决方案:

    创建:

    du -csxb /path | md5sum > file
    
    ls -alR -I dev -I run -I sys -I tmp -I proc /path | md5sum > /tmp/file
    
    检查:

    du -csxb /path | md5sum -c file
    
    ls -alR -I dev -I run -I sys -I tmp -I proc /path | md5sum -c /tmp/file
    

    md5sum
    对我来说很好,但我在
    排序
    和文件名排序方面遇到了问题。因此,我按照
    md5sum
    结果进行排序。为了创建可比较的结果,我还需要排除一些文件

    
    找到-类型f-print0\
    |xargs-r0 md5sum\
    |grep-v“.env”\
    |grep-v“vendor/autoload.php”\
    |grep-v“供应商/编写者/”\
    |排序-d\
    |md5sum
    

    我想补充一点,如果您试图对git存储库中的文件/目录执行此操作以跟踪它们是否已更改,那么这是最好的方法:

    git log -1 --format=format:%H --full-diff <file_or_dir_name>
    

    最后一个标记是否应为\;?对于subdir,使用类似于
    cat**.py
    | md5sum+1:非常有趣!您是说不同文件系统类型之间的顺序可能不同,还是在同一文件系统中的顺序可能不同?两者都有。它只取决于目录项的顺序