Пропозиція ire_and_curses щодо використання tar c <dir>
має деякі проблеми:
- tar обробляє записи каталогу в тому порядку, в якому вони зберігаються у файловій системі, і немає можливості змінити цей порядок. Це ефективно дає абсолютно різні результати, якщо у вас є "однаковий" каталог у різних місцях, і я не знаю, як це виправити (tar не може "сортувати" свої вхідні файли у певному порядку).
- Мені зазвичай цікаво, чи однакові номери групи і власника, не обов'язково, чи однакові рядкові представлення групи / власника. Це відповідає тому, що, наприклад,
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
забезпечити надійний порядок сортування по всіх системах
- Це не відрізняє каталог "name \ nwithanewline" та два каталоги "name" та "withanewline", але шанс виникнення цього видається дуже малоймовірним. Зазвичай це фіксується
-print0
прапором, find
але оскільки тут відбуваються інші речі, я бачу лише рішення, які б ускладнювали команду, тоді це варто.
PS: одна з моїх систем використовує обмежену службову скриньку, find
яка не підтримує -exec
ні -print0
прапори, а також додає '/' для позначення каталогів, тоді як Findutils не здається, тому для цієї машини мені потрібно запустити:
dir=<mydir>; (find "$dir" -type f | while read f; do md5sum "$f"; done; find "$dir" -type d | sed 's#/$##') | LC_ALL=C sort | md5sum
На щастя, у мене немає файлів / каталогів з новими рядками в їхніх назвах, тому це не проблема в цій системі.