Answers:
该md5deep工具是为正是为此目的而开发。许多Linux发行版都以软件包形式提供它。
-o
选项来处理文件类型。
如果您不想将其存档,则可以执行以下操作
diff <(find folder1) <(find folder2)
您可能需要调整find
命令以使其更加准确。
编辑
您可以添加-exec
到find调用中以比较文件的内容。类似于以下内容:
diff <(find folder1 -type f -exec md5sum {} \; | sort) <(find folder2 -type f -exec md5sum {} \; | sort)
请记住,您可能想对此进行调整。
一种测试方法是根据文件夹及其子文件夹中所有文件的串联生成md5sum。请记住,这还要求文件具有相同的名称(因为它们必须具有相同的排序顺序)。下面的代码应该工作:
#!/bin/bash
shopt -s nullglob
shopt -s globstar || { printf '%s\n' 'Bash 4 is required for globstar.' ; exit 1 ; }
(( $# == 2 )) || { printf '%s\n' "Usage: ${0##*/} olddir newdir" ; exit 2 ; }
for _file in "$1"/**/*; do [[ -f ${_file} && ! -L ${_file} ]] && _files_in_old_dir+=( "${_file}" ); done
for _file in "$2"/**/*; do [[ -f ${_file} && ! -L ${_file} ]] && _files_in_new_dir+=( "${_file}" ); done
(( ${#_files_in_old_dir[@]} )) || { printf '%s\n' 'No files in old dir.' ; exit 3 ; }
(( ${#_files_in_new_dir[@]} )) || { printf '%s\n' 'No files in new dir.' ; exit 4 ; }
_md5_old_dir=$(cat "${_files_in_old_dir[@]}" | md5sum)
_md5_new_dir=$(cat "${_files_in_new_dir[@]}" | md5sum)
{ [[ ${_md5_old_dir} == "${_md5_new_dir}" ]] && (( ${#_files_in_old_dir[@]} == ${#_files_in_new_dir[@]} )) ; } && printf '%s\n' 'Folders are identical.' || { printf '%s\n' 'Folders are not identical.' ; exit 3 ; }
如果您真正关心文件名等,则可以使用循环来比较${_files_in_old_dir}
和中的内容${_files_in_new_dir}
。这在大多数情况下都应该起作用(它至少检查目录及其子目录中的文件数)。
globstar
。有什么错误?
我注意到原始帖子比较旧,但是,我认为这些信息对于那些正在寻找一种解决方案来验证文件是否正确复制的人仍然很有价值。Rsync可能是复制数据的最佳方法,此线程中给出的答案也不错,但是对于那些没有Linux经验的人,我将尝试给出更详细的解释。
场景:您只是将数据从磁盘复制到另一个磁盘,其中包含许多子目录和文件。您要验证是否正确复制了所有数据。
首先通过发出命令检查md5deep是否已安装md5deep -v
。
如果收到类似“找不到命令”之类的消息,请通过安装md5deep apt-get install md5deep
。
假设您只想处理常规文件。如果要处理其他类型的文件,请参考md5deep手册中的-o标志。(man md5deep
)
现在您可以使用了,我们假设您将文件从复制/mnt/orginal
到/mnt/backup
,用这些文件替换您正在使用的任何目录。
首先更改到源目录,这是您复制或备份的文件的原始源:
cd /mnt/orginal
然后对每个文件进行校验和:
md5deep -rel -o f . >> /tmp/checksums.md5
该命令说明:
-r
启用递归模式
-e
显示进度指示器
-l
启用相对文件路径。
-o f
仅适用于常规文件(不适用于阻止设备,命名管道等)
.
告诉md5deep从当前目录开始。
>> /tmp/checksums.md5
告诉md5deep将所有输出重定向到/tmp/checksums.md5
。
请注意,如果您要覆盖的早期版本中的内容/tmp/checksums.md5
,请使用>
和不>>
请注意,此命令可能需要花费相当长的时间,具体取决于io-speed和数据的大小。您可以尝试使用nice和/或ionice来提高md5deep的性能,但这超出了此答案的范围。
校验和的创建完成后,您现在将拥有一个文件,其中包含类似于以下内容的条目:
69c0a826b29c8f40b7ca5e56e53d7f83 ./oldconfig-11-09-2013/etc2/apm/event.d/20hdparm 651f3c7f79a14332f9fa7bb368039210 ./oldconfig-11-09-2013/etc2/apm/event.d/anacron 50d89784c1e201f68b-11b /etc2/apm/scripts.d/alsa e9b9131660a8013983bc5e19d7d669eb ./oldconfig-11-09-2013/etc2/ld.so.cache
第一列是md5校验和,第二列是校验和所属文件的相对路径。
如果要查看校验和文件中存在多少个文件,请发出以下命令:
wc /tmp/checksums.md5 -l
现在,您要检查复制的数据是否正确:
cd /mnt/backup
md5deep -o f -reX /tmp/checksums.md5 . >> /tmp/compare.result
与我们创建校验和时的唯一区别是-X,如果checksums.md5文件中的条目不匹配,它将显示文件的当前哈希。因此,在测试结束时(如果/tmp/compare.result
为空),由于校验和匹配,您可以相信所有文件都已正确复制。
请注意,仅/tmp/checksums.md5
会检查文件中列出的文件的校验和是否正确,如果目录中还有其他文件,则/mnt/backup
md5deep不会将这些通知给您。
笔记:
您不一定必须使用重定向来存储输出文件。有关更多信息,请参见md5deep手册。
您可能必须以root用户身份运行md5deep命令,具体取决于要处理的文件的权限。
如果要递归检查两个目录之间的差异/path1
,/path2
而不使用md5deep
:
diff <(cd /path1 && find . -type f |xargs md5) <(cd /path2 && find . -type f |xargs md5)
说明:
path1
使所打印的所有行都find
相对于path1
(cd /path1
)&& find . -type f
find
作为md5
(| xargs md5
)的输入如果两者之间有任何差异,则输出将如下所示:
< MD5 (./index.html) = 36b01762f0329b2c12a5186520c7d78a
< MD5 (./inline.js) = ce99823a4b2c24839a727c5781f59a36
< MD5 (./main.js) = 3a597404d3ba7f0a6e3cb093ef57ebb2
---
> MD5 (./index.html) = 3a3d7663a7b2871ff37b9081a53593f9
> MD5 (./inline.js) = 1bbd0ecfc75b578413105c6b9009f9b3
> MD5 (./main.js) = 0f44abe5084add3cabdc39feec0c699878c78
sudo apt-get install md5deep
md5deep -rel /path/to/your/directory/ > directory_hash.md5
md5deep -X directory_hash.md5 -r /path/to/your/second/direcotory
感谢。