Der richtige Weg hängt genau davon ab, warum Sie fragen:
Option 1: Nur Daten vergleichen
Wenn Sie nur einen Hash des Dateiinhalts des Baums benötigen, ist dies der Trick:
$ find -s somedir -type f -exec md5sum {} \; | md5sum
Dabei werden zunächst alle Dateiinhalte einzeln in vorhersehbarer Reihenfolge zusammengefasst und anschließend die Liste der zu hashenden Dateinamen und MD5-Hashes selbst übergeben. Dabei wird ein einziger Wert angegeben, der sich nur ändert, wenn sich der Inhalt einer der Dateien in der Baumstruktur ändert.
Funktioniert leider find -snur mit BSD find (1), verwendet unter macOS, FreeBSD, NetBSD und OpenBSD. Um auf einem System mit GNU oder SUS etwas Vergleichbares zu finden (1), benötigen Sie etwas Hässlicheres:
$ find somedir -type f -exec md5sum {} \; | sort -k 2 | md5sum
Wir haben find -smit einem Anruf zu ersetzt sort. Das -k 2Bit weist es an, den MD5-Hash zu überspringen, sodass nur die Dateinamen, die sich in Feld 2 bis zum Zeilenende befinden, nach sortAbrechnung sortiert werden .
Diese Version des Befehls weist eine Schwachstelle auf. Dies kann zu Verwirrung führen, wenn Dateinamen mit Zeilenumbrüchen enthalten sind, da der sortAufruf wie mehrere Zeilen aussieht . Die find -sVariante hat dieses Problem nicht, da das Durchlaufen und Sortieren des Baumes innerhalb desselben Programms erfolgt find.
In beiden Fällen ist die Sortierung erforderlich, um Fehlalarme zu vermeiden: Die gängigsten Unix / Linux-Dateisysteme verwalten die Verzeichnislisten nicht in einer stabilen, vorhersehbaren Reihenfolge. Sie erkennen dies möglicherweise nicht an der Verwendung von lsund solchen, die den Verzeichnisinhalt für Sie unbemerkt sortieren. findwithout -soder ein sortAufruf druckt Dateien in der Reihenfolge aus, in der das zugrunde liegende Dateisystem sie zurückgibt. Dies führt dazu, dass dieser Befehl einen geänderten Hashwert ausgibt, wenn sich die Reihenfolge der Dateien ändert, die als Eingabe übergeben werden.
Möglicherweise müssen Sie die md5sumBefehle in md5oder eine andere Hash-Funktion ändern . Wenn Sie eine andere Hash-Funktion auswählen und die zweite Form des Befehls für Ihr System benötigen, müssen Sie den sortBefehl möglicherweise entsprechend anpassen . Eine weitere Falle ist, dass einige Datensummierungsprogramme überhaupt keinen Dateinamen ausschreiben, zum Beispiel das alte Unix- sumProgramm.
Diese Methode ist etwas ineffizient und ruft md5sumN + 1-mal auf, wobei N die Anzahl der Dateien im Baum ist. Dies ist jedoch ein notwendiger Kostenfaktor, um das Durchsuchen von Datei- und Verzeichnismetadaten zu vermeiden.
Option 2: Vergleichen Sie Daten und Metadaten
Wenn Sie feststellen müssen, dass sich in einem Baum etwas geändert hat, und nicht nur der Dateiinhalt, bitten Sie tardarum, den Verzeichnisinhalt für Sie zu packen, und senden Sie ihn dann an md5sum:
$ tar -cf - somedir | md5sum
Da tarauch Dateiberechtigungen, Eigentumsrechte usw. angezeigt werden, erkennt dies auch Änderungen an diesen Dingen, nicht nur Änderungen am Dateiinhalt.
Diese Methode ist erheblich schneller, da sie nur einen Durchlauf über den Baum macht und das Hash-Programm nur einmal ausführt.
Wie bei der findoben beschriebenen Methode tarwerden Dateinamen in der Reihenfolge verarbeitet, in der das zugrunde liegende Dateisystem sie zurückgibt. Möglicherweise können Sie in Ihrer Anwendung sicher sein, dass dies nicht der Fall ist. Ich kann mir mindestens drei verschiedene Nutzungsmuster vorstellen, bei denen dies wahrscheinlich der Fall ist. (Ich werde sie nicht auflisten, da wir uns in einem nicht näher definierten Gebiet bewegen. Jedes Dateisystem kann hier unterschiedlich sein, selbst von einer Version des Betriebssystems zur nächsten.)
Wenn Sie falsch positive Ergebnisse erhalten, würde ich empfehlen, die find | cpioOption in Gilles 'Antwort zu wählen .
find .stattdessen zu verwendenfind somedir. Auf diese Weise sind die Dateinamen identisch, wenn verschiedene zu suchende Pfadangaben angegeben werden. Das kann schwierig sein :-)