
Есть ли в каком-либо дистрибутиве Linux способ выполнить проверку md5sum или sha1 во время передачи файла с локального раздела на раздел NFS?
Пример:
У меня есть смонтированный диск NFS и очень большой файл на локальном диске. Я хотел бы перенести этот файл на смонтированный диск NFS и в то же время выполнить проверку md5. Я нашел много скриптов, которые выполняли бы проверку md5 после копирования файла на удаленный диск, но поскольку это очень большой файл, 100 ГБ+, я хотел бы узнать, есть ли способ воспользоваться тем фактом, что файл уже проверяется во время передачи.
решение1
Я не знаю стандартной утилиты Linux, которая может это сделать. Если файл поместится в кэше на основе памяти, не будет таким уж неэффективным сначала выполнить md5sum, а затем скопировать (копия получит данные из памяти).
Вы можете использовать следующую комбинацию:
cat filename | tee remote_output_name | md5sum
который вы могли бы изменить, чтобы напрямую проверить сумму, напечатанную с помощью md5sum
сохраненного md5. Это считывает файл с диска только один раз.
Предполагая, что вы сгенерировали check.md5
с помощью
cd dir_with_big_files
md5sum * > check.md5
, следующая программа Python будет копировать и проверять один файл, читая/записывая по 64 Мб за раз. Сохраните его как /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 доступны через внешний репозиторийрепозитории сертификатовнапример.
Чтобы скопировать файл частями по 8 МБ и вычислить MD5-сумму всех данных, которая выводится в STDERR:
dcfldd if=/path/to/input bs=8M hash=md5 of=/path/to/outputfile
Чтобы скопировать файл блоками по 8 МБ, вычисляя хеш SHA256 всех данных плюс сумму SHA256 для каждого блока по 64 МБ:
dcfldd if=/path/to/input bs=8M hash=SHA256 hashwindow=64M of=/path/to/outputfile
Выходной файл для вычисленного хеша также может быть предоставлен путем указания файла через hashlog
параметр. При вычислении нескольких хешей отдельные выходные данные могут быть указаны через eg md5log=FILE1.log sha256log=FILE2.log
.
решение3
Вы можете использовать внешнюю программу ( crcsum
), которая расширяет cp
и mv
с контрольной суммой: