背景
我即将将文件从旧 NAS 迁移到新 NAS,并希望验证数据完整性。旧的 NAS (Debian) 使用 Linux Ext3 文件系统,而新的 NAS (FreeNAS) 基于 ZFS。为了加快完整性验证,我尝试使用分类方法:
- 首先验证所有文件大小
- 其次 md5 哈希每个文件的前 512 个字节
- 最后md5散列整个文件
这个想法是,前两个步骤将过滤掉明显损坏的文件,并且比对 TB 级文件批量运行 md5 进行检测要快得多。
问题
我构建了一个 bash 命令,用于执行目录结构的 md5 哈希,并根据文件名对输出进行排序,以确保 Linux NAS 上的确定性顺序。
#find somedir -type f -exec md5sum {} \; | sort -k 34;
12e761f96223145aa63f4f48f252d7fb /somedir/foo.txt
18409feb00b6519c891c751fe2541fdc /somedir/bar.txt
但是如果我只想对每个文件的前 512 字节进行 md5,如何修改上面的内容呢?
答案1
您可以dd
仅使用管道将前 512 个字节传输到md5sum
.但是这会导致md5sum
忘记文件名,因此另外-
再次替换为文件名。
find . -type f -exec sh -c "dd if={} bs=512 count=1 2>/dev/null | md5sum | sed s\|-\|{}\|" \; | sort -k 34;
答案2
接受的答案对我不起作用。内部对于带有特殊字符的文件{}
失败exec
。因此,我改为使用 GNU parallel
(安装其最新版本以使以下解决方案起作用)。
使用parallel
,{}
对于带有特殊字符的文件不会出现错误行为。此外,parallel
由于它将进程分布在多个核心上,因此整个过程变得更快。这是对我有用的parallel
:
find . -type f | parallel 'dd if={} bs=512 count=1 2>/dev/null | md5sum | tr -d "\n"; echo {};' | sort -k34;