复制文件时的 md5 或 sha1

复制文件时的 md5 或 sha1

在任何 Linux 发行版中,是否有一种方法可以在文件从本地分区传输到 NFS 分区时执行 md5sum 或 sha1 检查?

例子:

我的本地驱动器上有一个 NFS 安装驱动器和一个非常大的文件。我想将该文件传输到 NFS 安装的驱动器,同时进行 md5 检查。我发现很多脚本在将文件复制到远程驱动器上后会执行 md5,但由于它是一个非常大的文件 100GB+,我想知道是否有一种方法可以利用该文件已经被复制的事实传输时呈红色。

答案1

我不知道有哪个标准 Linux 实用程序可以做到这一点。如果文件适合基于内存的缓存,那么首先执行 md5sum 然后复制(复制将从内存中获取数据)的效率不会那么低。

您可以使用以下组合:

cat filename | tee remote_output_name | md5sum

您可以修改它以直接根据md5sum存储的 md5 检查打印的总和。这仅从光盘读取文件一次。

假设你已经生成了check.md5一个

cd dir_with_big_files
md5sum * > check.md5

,以下 Python 程序将复制和检查单个文件,一次读取/写入 64Mb。将其保存为 /usr/local/bin/chkcopy,chmod +x /usr/local/chkcopy并使用chkcopy file_name check.md5 destination_filename_or_dir

#! /usr/bin/env python

import sys, os, hashlib

m = hashlib.md5()
file_name = sys.argv[1]
md5_name = sys.argv[2]
out_name = sys.argv[3]
if os.path.isdir(out_name):
    out_name = os.path.join(out_name, file_name)
BUF_SIZE = 64 * (1024 ** 2)

with open(file_name, 'rb') as ifp:
    with open(out_name, 'wb') as ofp:
        buf = ifp.read(BUF_SIZE)
        while buf:
            m.update(buf)
            ofp.write(buf)
            buf = ifp.read(BUF_SIZE)
with open(md5_name) as fp:
    for line in fp:
        md5, fn = line.rstrip().split('  ', 1)
        if fn == file_name:
            assert m.hexdigest() == md5
            break
    else:
        print('no md5 found for ' + file_name)

答案2

dd存在一个具有扩展功能的众所周知的分支,称为dcfldd我已经使用了很多年了,或者是一个dd名为的修补版本dc3dd具有有些相似的功能。

这两种工具都可以在复制过程中执行散列(如果需要,甚至可以同时使用多个散列类型)。可以对块和/或整个数据流计算哈希值。

一些发行版(例如 debian)直接在其存储库中提供软件包,fedora 的软件包可通过外部获取证书存储库例如。

要复制 8MiB 块中的文件并计算整个数据的 MD5sum,并将其打印到 STDERR:

dcfldd if=/path/to/input bs=8M hash=md5 of=/path/to/outputfile

要复制 8MiB 块中的文件,计算整个数据的 SHA256 哈希加上每个 64MiB 块上的 SHA256sum:

dcfldd if=/path/to/input bs=8M hash=SHA256 hashwindow=64M of=/path/to/outputfile

还可以通过参数指定文件来提供计算出的哈希值的输出文件hashlog。当计算多个哈希值时,可以通过例如指定单独的输出md5log=FILE1.log sha256log=FILE2.log

答案3

您可以使用外部程序(crcsum),它扩展cpmv带有校验和:

https://sourceforge.net/projects/crcsum/

相关内容