Ich schreibe ein Shell-Skript, das shasum
überprüft, ob sich der Inhalt eines Verzeichnisses geändert hat.
Unter Linux und FreeBSD shasum
ist das Verhalten gleich shasum <directory>
, aber unter MacOS shasum
bekomme ich Hashesnur für Dateien.
FreeBSD
$ shasum CONTENTS/
7f986e5e5289c59db1bba48df92ffe4707830aaa CONTENTS/
Linux
$ shasum CONTENTS/
7f986e5e5289c59db1bba48df92ffe4707830aaa CONTENTS/
Mac OS
$ shasum CONTENTS/
shasum: CONTENTS/:
Wie kann ich den Hash eines Verzeichnisses in MacOS berechnen?
VERSUCH 1: TAR mit Pipes verwenden
Habe versucht, es zu verwenden, aber es scheint, dass diese Tar-Option unter MacOS nicht funktioniert.
tar cO CONTENTS/ | shasum
tar: Option -O is not permitted in mode -c
da39a3ee5e6b4b0d3255bfef95601890afd80709 -
VERSUCH 2: Verwenden von FIND/EXEC
Es war konsistent zwischen MacOS und FreeBSD, aber Linux gab einen seltsamen Hash zurück
find CONTENTS -type f -exec shasum {} \; | sort -k 2 | shasum
Linux
c2ddb9bc5f543e956f5cdcc76750cb78cc5f26f3
FreeBSD
3ac2a9d4e2fc5d2d2ec3c7f612e680990cc35824
Mac OS
3ac2a9d4e2fc5d2d2ec3c7f612e680990cc35824
WEITERE ERKENNTNISSE ZU TAR
tar
wäre ausgezeichnet, da es einen Ordner "archiviert" und dann könnte ich shasum
es, jedoch ist die Reihenfolge, wie tar
"durch die Ordnerstruktur gehen"nicht betriebssystemübergreifend konsistent. Wie einige Helfer in den Kommentaren erwähnt haben, sollte ich tar
in allen Systemen die gleiche Version von verwenden.
Nur ein Beispiel, auf System 1 habe ich diese Reihenfolge:
drwxr-xr-x 0 root wheel 0 27 Jul 07:23 usr/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f1/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f1/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f1/f0/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f1/f0/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f2/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f2/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f2/f1/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f2/f1/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f2/f1/f0/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f2/f1/f0/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f3/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f3/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f3/f2/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f3/f2/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f3/f2/f1/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f3/f2/f1/aaa
und auf System 2 habe ich folgende Reihenfolge:
drwxr-xr-x 0 root wheel 0 27 Jul 07:23 usr/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f1/
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f2/
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f3/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f3/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f3/f2/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f3/f2/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f3/f2/f1/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f3/f2/f1/aaa
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f2/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f2/f1/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f2/f1/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f2/f1/f0/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f2/f1/f0/aaa
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f1/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f1/f0/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f1/f0/aaa
Vom tar
Standpunkt aus ist alles gut, aber aufgrund der Reihenfolge shasum
ergibt sich ein anderer Hash.
ABSCHLUSS
shasum
ist unter Linux und BSDs konsistent, um einen einzelnen Datei-Hash zu prüfen, aber wenn es um Verzeichnisse geht, besteht die Konsistenz nur unter MacOS und FreeBSD, möglicherweise aufgrund der Art und Weise, wie die Dateien sortiert werden.
Wenn die Sortierung mit dem Befehl erzwungen wird find
, wird Konsistenz nur unter FreeBSD und MacOS erreicht; diese Methode ist jedoch zeitaufwändig, da das Berechnen der Hashes für jede einzelne Datei und anschließend des gesamten Struktur-Hashes sehr viel Zeit in Anspruch nimmt.
Die Verwendung tar
zum Erstellen einer temporären Datei und das anschließende Ausführen von shasum
ist zwischen Linux und BSDs ebenfalls inkonsistent, möglicherweise aufgrund unterschiedlicher Archivierungsmethoden.
Ich glaube, der einzige Weg nach vorn ist,meine Lösung neu gestalten.
Antwort1
mtree
ist das gewünschte Werkzeug.
Vermuten:
$ mkdir foo
$ date > foo/date1; sleep 3
$ date > foo/date2; sleep 3
$ date > foo/date3
$ grep . foo/*
foo/date1:Wed Jul 24 16:11:32 PDT 2019
foo/date2:Wed Jul 24 16:11:35 PDT 2019
foo/date3:Wed Jul 24 16:11:38 PDT 2019
$ find . -ls
7318841 0 drwxr-xr-x 3 admin staff 102 Jul 24 16:11 .
7318847 0 drwxr-xr-x 5 admin staff 170 Jul 24 16:11 ./foo
7318849 8 -rw-r--r-- 1 admin staff 29 Jul 24 16:11 ./foo/date1
7318851 8 -rw-r--r-- 1 admin staff 29 Jul 24 16:11 ./foo/date2
7318853 8 -rw-r--r-- 1 admin staff 29 Jul 24 16:11 ./foo/date3
Erstellen Sie ein Referenzmanifest des Verzeichnisses foo
und speichern Sie es in foo.mtree
:
$ mtree -c -K sha256digest -p foo > foo.mtree
Gehen Sie jetzt und bearbeiten Sie eine beliebige Datei in diesem Verzeichnis.
$ touch foo/date3
Führen Sie es mtree
erneut aus und übergeben Sie das Manifest, das Sie zuvor erstellt haben. mtree
Sie erfahren dann, was sich geändert hat:
$ mtree -p foo < foo.mtree || echo fail
date3 changed
modification time expected Wed Jul 24 16:11:38 2019 found Wed Jul 24 16:14:00 2019
fail
$ echo '$ date > foo/date2' >> bar
$ mtree -p foo < foo.mtree || echo fail
date2 changed
modification time expected Wed Jul 24 16:11:35 2019 found Wed Jul 24 16:19:40 2019
SHA-256 expected c76a568f08d98c2830f2fdfb42415c3ec15341b8741450d4bbd863f1d5c4c691 found ddcf8d07785bfe4d031a989339835dc3b8b44653019568dcee612c44fc8e2f70
date3 changed
modification time expected Wed Jul 24 16:11:38 2019 found Wed Jul 24 16:14:00 2019
fail
Alle Dateien, die seit der Erstellung des Manifests fehlen foo
oder hinzugefügt wurden, werden ebenfalls gemeldet:
$ mv foo/date1 foo/date4
$ mtree -p foo < foo.mtree || echo fail
. changed
modification time expected Wed Jul 24 16:11:38 2019 found Wed Jul 24 16:21:38 2019
date2 changed
modification time expected Wed Jul 24 16:11:35 2019 found Wed Jul 24 16:19:40 2019
SHA-256 expected c76a568f08d98c2830f2fdfb42415c3ec15341b8741450d4bbd863f1d5c4c691 found ddcf8d07785bfe4d031a989339835dc3b8b44653019568dcee612c44fc8e2f70
date3 changed
modification time expected Wed Jul 24 16:11:38 2019 found Wed Jul 24 16:14:00 2019
date4 extra
./date1 missing
fail
Antwort2
Rmlintwird tun, was (glaube ich) Sie wollen.
Relevante Punkte:
- Standardmäßig wird SHA nicht verwendet, dies kann aber angefordert werden.
- Es kann über Homebrew auf MacOS installiert werden.
- Standardmäßig berechnet es keine Prüfsumme für ein einzelnes angegebenes Verzeichnis. Es kann angewiesen werden, Prüfsummen für alle Verzeichnisse ab einem bestimmten Startpunkt zu berechnen, um „doppelte“ Verzeichnisse unterhalb dieses Punkts zu finden. Als Nebeneffekt wird es jedoch auch genau das tun, was Sie anscheinend verlangen.
- Für das, was Sie suchen, ist das vielleicht übertrieben und es kann eine Weile dauern, bis Sie herausgefunden haben, welche Optionsflags sich am besten eignen, aber es ist recht robust.
- Herauszufinden, welche Flags zu verwenden sind, kann schwierig sein. Verzeichnisprüfsummen zu erhalten ist einfach genug, aber es zu bekommennichtandere Dinge tun, kann schwierig sein. (Um es klarzustellen: Es ändert eigentlich nichts. Es generiert höchstens ein Shell-Skript, das Sie später manuell ausführen können, um Dinge bei Bedarf zu ändern. Was Sie anscheinend brauchen, sind die JSON- und/oder CSV-Ausgabedateien, die Ihnen die gewünschte Verzeichnisprüfsumme liefern.)
Ich verwende rmlint in einem Bash-Skript, um doppelte Verzeichnisse zu finden. Hier ist ein Befehl, der mindestens das tut, was Sie wollen, und so wenig anderes wie möglich:
rmlint "base/dir/to/start/from" --see-symlinks --hidden --algorithm=sha256 --types=none,duplicatedirs --no-backup -o csv:log.csv