Das Programm md5sum liefert keine Prüfsummen für Verzeichnisse. Ich möchte eine einzelne MD5-Prüfsumme für den gesamten Inhalt eines Verzeichnisses erhalten, einschließlich Dateien in Unterverzeichnissen. Das heißt, eine kombinierte Prüfsumme aus allen Dateien. Gibt es dafür eine Möglichkeit?
Akzeptierte Antwort:
Der richtige Weg hängt davon ab, warum Sie genau fragen:
Option 1:Nur Daten vergleichen
Wenn Sie nur einen Hash des Dateiinhalts des Baums benötigen, reicht dies aus:
$ find -s somedir -type f -exec md5sum {} ; | md5sum
Dieser fasst zunächst alle Dateiinhalte einzeln in einer vorhersehbaren Reihenfolge zusammen und übergibt dann diese Liste von Dateinamen und MD5-Hashes, die selbst gehasht werden sollen, wobei ein einzelner Wert angegeben wird, der sich nur ändert, wenn sich der Inhalt einer der Dateien im Baum ändert.
Leider find -s
funktioniert nur mit BSD find(1), verwendet in macOS, FreeBSD, NetBSD und OpenBSD. Um etwas Vergleichbares auf einem System mit GNU oder SUS find(1) zu bekommen, brauchen Sie etwas Hässlicheres:
$ find somedir -type f -exec md5sum {} ; | sort -k 2 | md5sum
Wir haben das Verhalten von BSD find -s
nachgeahmt durch Hinzufügen eines Aufrufs von sort
. Das -k 2
bit weist es an, den MD5-Hash zu überspringen, also sortiert es nur die Dateinamen, die sich in Feld 2 bis zum Zeilenende befinden, nach sort
rechnen.
Diese Version des Befehls hat eine Schwachstelle, nämlich dass sie leicht verwirrt werden kann, wenn Sie irgendwelche Dateinamen mit Zeilenumbrüchen darin haben, weil es für den sort
wie mehrere Zeilen aussehen wird Forderung. Das find -s
Variante hat dieses Problem nicht, da das Traversieren und Sortieren des Baums innerhalb desselben Programms geschieht, find
.
In jedem Fall ist die Sortierung notwendig, um Fehlalarme zu vermeiden:Die gängigsten Unix/Linux-Dateisysteme verwalten die Verzeichnislisten nicht in einer stabilen, vorhersagbaren Reihenfolge. Sie werden dies möglicherweise nicht erkennen, wenn Sie ls
verwenden und solche, die den Inhalt des Verzeichnisses stillschweigend für Sie sortieren. Aufruf von find
ohne die Ausgabe auf irgendeine Weise zu sortieren, wird die Reihenfolge der Zeilen in der Ausgabe mit der Reihenfolge übereinstimmen, die das zugrunde liegende Dateisystem zurückgibt, was dazu führt, dass dieser Befehl einen geänderten Hash-Wert zurückgibt, wenn sich die Reihenfolge der ihm als Eingabe übergebenen Dateien ändert, sogar wenn die Daten identisch bleiben.
Sie fragen sich vielleicht, ob der -k 2
bit im GNU sort
obiger Befehl ist notwendig. Da der Hash der Dateidaten ein adäquater Proxy für den Dateinamen ist, solange sich der Inhalt nicht geändert hat, erhalten wir keine Fehlalarme, wenn wir diese Option fallen lassen, wodurch wir denselben Befehl sowohl mit GNU als auch mit BSD verwenden können sort
. Beachten Sie jedoch, dass es eine kleine Chance (1:2 mit MD5) gibt, dass die genaue Reihenfolge der Dateinamen nicht mit der teilweisen Reihenfolge übereinstimmt, die ohne -k 2
auskommt geben kann, wenn es jemals zu einer Hash-Kollision kommt. Denken Sie jedoch daran, dass dieser ganze Ansatz für Sie wahrscheinlich nicht in Frage kommt, wenn solch kleine Chancen einer Diskrepanz für Ihre Anwendung von Bedeutung sind.
Möglicherweise müssen Sie die md5sum
ändern Befehle an md5
oder eine andere Hash-Funktion. Wenn Sie eine andere Hash-Funktion wählen und die zweite Form des Befehls für Ihr System benötigen, müssen Sie möglicherweise die sort
anpassen Befehl entsprechend. Eine weitere Falle ist, dass einige Datensummierungsprogramme überhaupt keinen Dateinamen ausschreiben, ein Paradebeispiel ist das alte Unix sum
Programm.
Diese Methode ist etwas ineffizient und ruft md5sum
auf N+1 Mal, wobei N die Anzahl der Dateien im Baum ist, aber das sind notwendige Kosten, um das Hashing von Datei- und Verzeichnismetadaten zu vermeiden.
Option 2:Daten und vergleichen Metadaten
Wenn Sie in der Lage sein müssen, irgendetwas zu erkennen in einem Baum hat sich geändert, nicht nur der Dateiinhalt, fragen Sie tar
um den Inhalt des Verzeichnisses für Sie zu packen, und senden Sie ihn dann an md5sum
:
$ tar -cf - somedir | md5sum
Denn tar
sieht auch Dateiberechtigungen, Eigentum usw., dies wird auch Änderungen an diesen Dingen erkennen, nicht nur Änderungen an Dateiinhalten.
Diese Methode ist erheblich schneller, da sie nur einen Durchgang über den Baum macht und das Hash-Programm nur einmal ausführt.
Wie beim find
basierte Methode oben, tar
wird Dateinamen in der Reihenfolge verarbeiten, in der das zugrunde liegende Dateisystem sie zurückgibt. Es kann durchaus sein, dass Sie in Ihrer Anwendung sicher sein können, dass Sie dies nicht verursachen werden. Ich kann mir mindestens drei verschiedene Nutzungsmuster vorstellen, bei denen dies wahrscheinlich der Fall ist. (Ich werde sie nicht auflisten, weil wir in ein nicht spezifiziertes Verhaltensgebiet geraten. Jedes Dateisystem kann hier unterschiedlich sein, sogar von einer Version des Betriebssystems zur nächsten.)
Wenn Sie feststellen, dass Sie falsch positive Ergebnisse erhalten, würde ich empfehlen, mit find | cpio
Option in Gilles Antwort.