Предложение ire_and_curses об использовании tar c <dir>
имеет некоторые проблемы:
- tar обрабатывает записи каталога в том порядке, в котором они хранятся в файловой системе, и изменить этот порядок невозможно. Это эффективно может дать совершенно разные результаты, если у вас есть «один и тот же» каталог в разных местах, и я не знаю способа исправить это (tar не может «сортировать» свои входные файлы в определенном порядке).
- Обычно меня волнует, совпадают ли номера groupid и ownerid, не обязательно, совпадают ли строковые представления группы / владельца. Это соответствует тому, что
rsync -a --delete
делает, например : он синхронизирует практически все (за исключением xattrs и acls), но он будет синхронизировать владельца и группу на основе их идентификаторов, а не строкового представления. Поэтому, если вы синхронизировались с другой системой, которая не обязательно имеет одинаковых пользователей / группы, вы должны добавить --numeric-owner
флаг в tar
- tar будет включать имя файла каталога, который вы проверяете, просто то, о чем нужно знать.
Пока нет решения для первой проблемы (или если вы не уверены, что это не влияет на вас), я бы не стал использовать этот подход.
На find
основе решения , предложенные выше , не являются также не хорошо , потому что они включают в себя только файлы, не каталоги, что становится проблемой , если вас контрольной суммы следует иметь в виду пустые каталоги.
Наконец, большинство предлагаемых решений не сортируются последовательно, потому что параметры сортировки могут быть разными в разных системах.
Это решение, которое я придумал:
dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum
Примечания об этом решении:
-
LC_ALL=C
для обеспечения надежного порядка сортировки в системах.
- Это не делает различий между каталогом «named \ nwithanewline» и двумя каталогами «named» и «withanewline», но вероятность этого кажется очень маловероятной. Обычно это исправляют с помощью
-print0
флага для, find
но, поскольку здесь происходят другие вещи, я могу видеть только решения, которые сделают команду более сложной, чем она того стоит.
PS: одна из моих систем использует ограниченный busybox, find
который не поддерживает -exec
ни -print0
флаги, а также добавляет '/' для обозначения каталогов, в то время как findutils find, похоже, не работает, поэтому для этой машины мне нужно запустить:
dir=<mydir>; (find "$dir" -type f | while read f; do md5sum "$f"; done; find "$dir" -type d | sed 's#/$##') | LC_ALL=C sort | md5sum
К счастью, у меня нет файлов / каталогов с символами новой строки в их именах, так что это не проблема для этой системы.