Durch das Hinzufügen der SHA1-Summe (die mathematisch garantiert zu einem lächerlich hohen Maß an Sicherheit führt, dass die Dateien entweder übereinstimmen, wenn die Hashwerte übereinstimmen, und die Hashwerte nicht übereinstimmen, wenn die Dateien nicht übereinstimmen), wird ein Maß an Datenintegrität hinzugefügt, um sich vor Fällen zu schützen Das Disk-Subsystem hat beim Schreiben möglicherweise einen (stillen) Fehler gemacht. Stumme Korruption ist selten, aber schleichend, wenn es passiert.
Natürlich könnten Sie immer noch verwirrende Ergebnisse haben, wenn Sie beim Lesen zufällige Fehler haben, aber in diesem Fall stimmen die Summen ohnehin nicht mit extrem hoher Sicherheit überein. Mit anderen Worten, wenn das System beschädigt ist (entweder der RAM-Speicher oder der Datenträger, der falsche Bits / umgedrehte Bits / beschädigte Daten erzeugt), wird dies fehlschlagen, wenn ein einfacher &&
Vorgang erfolgreich sein könnte, und die Wahrscheinlichkeit, dass dies rm
mit beschädigten Daten zur Leitung gelangt, verschwindet klein (da die meisten Fehler dazu neigen, Daten auf zufällige Weise zu beschädigen, sind die Chancen der zufälligen Änderung, die eine Hash-Kollision in SHA1 während des Rücklesens verursacht, atemberaubend klein.)
#!/bin/bash set -e set -o pipefail ORIGSUM=$(gzip -dc file.gz | tee >(xz > file.xz) | sha1sum) NEWSUM=$(unxz -c file.xz | sha1sum) if [ "$" = "$" ]; then rm file.gz; fi
Das set -e
Shell-Skript wird beendet, sobald eine Zeile des Skripts einen Exit-Code ungleich Null zurückgibt.
Dann benutzen wir den tee
Befehl, um die un-gzip - Ausgabe der Datei zu kopieren, sowohl den xz
Kompressor, und zum sha1sum
Programm. sha1sum
berechnet die SHA1-Summe der im gzipped-Archiv enthaltenen Originaldaten, indem sie vorübergehend in das sha1sum-Programm entpackt wird, das die Daten liest, um die Summe zu berechnen, und verwirft die Daten. Bei der Verwendung tee
müssen wir nur einmal die CPU-Kosten für das Entpacken der Datei bezahlen.
Dann führen wir einen zusätzlichen, rechenintensiven Schritt aus (für eine Super-Extra-Überprüfung), entfernen die xz-Komprimierung der Datei (vorübergehend in einen Stream) und leiten sie an sha1sum, um unsere SHA1-Summe "new file" zu erhalten.
Dann vergleichen wir die beiden Summen, und wenn sie nicht gleich sind, oder wenn eine oder beide eine Länge von Null haben, wird entweder ein Skriptfehler ausgegeben (der dank set -e
) endet, oder die Datei wird nicht angezeigt entfernt. else
Wenn Sie möchten, können Sie eine Klausel für die benutzerfreundliche Fehlerbehandlung implementieren. Dieses grundlegende Skript ist jedoch äußerst sicher, auch wenn es für Benutzer, die den Befehl interaktiv ausführen, nicht sehr informativ ist.
Am Ende wird die file.gz
Verknüpfung nur dann aufgehoben, wenn die unkomprimierten Inhalte von file.gz
und file.xz
zu dem Zeitpunkt, zu dem die Hashes berechnet wurden, exakt identisch sind, mit einem astronomisch hohen Maß an Sicherheit (die Wahrscheinlichkeit, dass etwas Schlimmes schief geht, wäre etwas wie 1 in 1 mit 300 Nullen danach). An diesem Punkt müssen Sie sich nur darum kümmern, dass die Daten beschädigt werden, nachdem das Skript beendet wurde. ;)
Performance
Dieses Skript wird mit der gleichen Geschwindigkeit wie das ursprüngliche Skript in der Frage ausgeführt, mit Ausnahme des Teils, der ausgeführt wird unxz
. Zum Glück ist das Dekomprimieren von LZMA extrem schnell, fast so schnell wie das normale Zip und so etwas um eine Größenordnung schneller als das Komprimieren in LZMA. Wenn Sie über eine schnelle CPU verfügen und die Dateien ausreichend klein sind, sollte dies nicht zu einer längeren Laufzeit des Skripts führen. Wenn Sie jedoch Wert auf die Integrität der Daten über die Leistung legen, ist dies ein klarer Gewinn.
Gutschrift bei fälliger Gutschrift
Diese Antwort auf StackOverflow hat mir beim Schreiben dieses Skripts wesentlich geholfen .