У меня есть домашний файловый сервер, на котором я использую Ubuntu.
Недавно один из моих накопителей заполнился, поэтому я взял другой и бросил его туда.
У меня очень большая папка, размер каталога составляет около 1,7 Тб и содержит приличное количество файлов.
я использовалGCPчтобы КОПИРОВАТЬ файлы со старого диска на новый, и, кажется, это сработало нормально.
Теперь я хочу проверить новый каталог на новом диске по сравнению с исходным каталогом на старом диске, прежде чем удалить данные со старого диска, чтобы освободить место. Я понимаю, что могу сделать проверку CRC, чтобы сделать это.
Как конкретно я могу это сделать?
решение1
Я бы просто использовал diff
команду:
diff -rq --no-dereference /path/to/old/drive/ /path/to/new/drive/
Это считывает и сравнивает каждый файл в дереве каталогов и сообщает о любых различиях. -r
Флаг сравнивает каталоги рекурсивно, в то время как -q
флаг просто выводит сообщение на экран, когда файлы различаются — в отличие от печати фактических различий (как это происходит для текстовых файлов). Флаг --no-dereference
может быть полезен, если есть символические ссылки, которые различаются, например, в одном каталоге — символическая ссылка, а в соответствующем каталоге — копия файла, на который была ссылка.
Если diff
команда выводитнет выхода, это означает, что деревья каталогов действительно идентичны; вы можете запустить , echo $?
чтобы убедиться, что его статус выхода — 0
, что указывает на то, что оба набора файлов одинаковы.
Я не думаю, что вычисление CRC или контрольных сумм особенно полезно в этом случае. Было бы разумнее, если бы два набора файлов находились в разных системах, и каждая система могла бы вычислять контрольные суммы для своего собственного набора файлов, так что по сети нужно было бы отправлять только контрольные суммы. Другая распространенная причина вычисления контрольных сумм — сохранение копии контрольных сумм для будущего использования.
решение2
rsyncчасто используется для копирования файлов вместо gcp
, но его также можно использовать для проверки копии, как бы она ни была сделана. Просто сделайте
rsync -niaHc /origfolder/ /copyfolder
Будьте внимательны и заканчивайте имя первой папки (источника) на /
. Возможные варианты:
-n
не копировать (не вносить никаких изменений)-i
перечислите различия-a
сохранить (т.е. сравнить, поскольку у нас есть-n
) разрешения, права собственности, символические ссылки и т.д. и рекурсивно пройтись по каталогам-H
сохранять жесткие ссылки-c
сравнить контрольные суммы
Вывод показывает код, детализирующий различия для каждого файла или каталога, которые отличаются. Если они одинаковы, вывода нет. Код содержит столбцы, YXcstpoguax
где каждый символ — это точка, .
если этот аспект сравнения в порядке, или буква:
Y is type of update:
< sent (not appropriate in this case)
> need to copy
c missing file or directory
h is hard link
. no update
* and rest of line is a message, eg *deleting
X file type: f file d dir L symlink D device S special file
c checksum differs. + new item " " same
s size differs
t timestamp differs
p permissions differ
o owner differ
g group differ
u (not used)
a acl differ
x extended attributes differ
Например,
.d..t...... a/b/ directory timestamp differs
cL+++++++++ a/b/d -> /nosuch2 symbolic link missing
cS+++++++++ a/b/f special file missing (a/b/f is a fifo)
>f..t...... a/b/ff file timestamp differs
hf a/b/xx1 => a/b/xx files should be a hard linked
cLc.t...... a/b/z -> /tmp/hi2 symbolic link to different name
cd+++++++++ a/c/ directory missing
>f+++++++++ a/c/i.10 missing file needs to be copied
Подробнее см . man rsync
ниже . Если у вас есть различия в 3-м или 4-м столбцах, то у вас серьезное повреждение данных. Другие флаги, такие как разные разрешения, владелец или временные метки, могут быть для вас менее важны. Если все файлы помечены как «отсутствующие», то вы, вероятно, указали не те каталоги для сравнения. Если вы уверены, запуск rsync без флага «исправит» различия.--itemize-changes
c
s
-n
решение3
У меня был тот же вопрос, и я использовалОтвет Энтони, с небольшой изюминкой.
Непосредственное применение этого ответа приведет к сбою в работе оборудования (например, ошибка ввода/вывода), что заставит diff завершить работу.
Я составил его ответ вместе сэтот ответ, и в целом сформулировать это так:
find /path/to/original -type f -exec bash -c 'diff -rq --no-dereference "$@" "/path/to/destination/$(sed -r "s/^.*(<first-common-ancestor>.*)$/\1/g" <<<"$@")"' bash {} \;
- Замените
/path/to/original
на путь к исходному каталогу, который вы скопировали. - Замените
/path/to/destination
на путь к целевому каталогу, в который вы скопировали. - Заменить
<first-common-ancestor>
общим предком каталога между ними. Пример: вы копируете из/media/foo/bar
в/media/test/dst/
, так чтоdst
после завершения операции копирования у , будет каталогbar
. Первый общий предокbar
здесь; потому что все файлы под нимbar
будут иметь тот же относительный путь.
Некоторые примечания:
- Части
bash -c
иbash {}
предназначены для выполнения безопасной замены имен файлов, чтобы обезопасить себя от возможных атак (например, повышения привилегий). - Часть
sed
заключается в удалении абсолютного пути к найденному файлу и использовании только относительного пути (это отличается от использованияexecdir
). Если вы не уверены, как это полезно, попробуйте удалить его и проверьте сообщения об ошибках :) - Для
<<<
чтения переменной как строки, а не как пути к файлу для чтения.