staging.inyokaproject.org

Datenintegrität dauerhaft gewährleisten

Status: Gelöst | Ubuntu-Version: Kubuntu 22.04 (Jammy Jellyfish)
Antworten |

Zoner

Anmeldungsdatum:
30. August 2019

Beiträge: 120

Ich habe in letzter Zeit sehr viele, sehr alte aber für mich wertvolle Daten (z.B. selbsterstelltes) zusammengesucht und auf verschiedene Backups verteilt. (quasi eine Inventur gemacht)

Nun habe ich aber das Problem, dass nicht wenige (teils mehrere jahrzehnte alte Daten, die über mehrere Datenträger gewandert sind) defekt sind. Lückenhafte Audiofiles, oder Bilder die garnicht oder nur noch zur Hälfte dargestellt werden als Beipsiel. Teilweise ist das nicht aufgefallen, weil sie ständig Ordnerweise umherkopiert aber nie geprüft wurden. Also irreperabel, da es den Ursprungsdatenträger nicht mehr gibt.

Nun möchte ich für die restlichen gesamten Daten sicherstellen, dass diese (für immer) bitgenau heile bleiben. Und da es keine lebenslang zuverlässigen Speicher gibt (zumindest bezahlbar für den Endkonsumenten), müssen die Daten regelmäßig geprüft werden. (Es geht dabei nur um Daten auf Wechseldatenträgern, die nur von mir manuell angefasst werden)

Als Beispiel: Ich habe eine Datei, dessen Checksums ich auslese (SHA1, SHA256 etc.) und in eine Textdatei kopiere. Ich verteile beide Daten auf verschiedene Backupdatenträger. Auf diese Weise kann ich langfristig feststellen, ob sich die Datei verändert hat (einzelne Bits zerfallen sind) und kann diese durch andere Backups (sofern diese die Checksumprüfung überstehen) ersetzen.

Natürlich ist das eine unmöglich zu bewerkstelligende Sisyphus Aufgabe, wenn man dieses Konzept händisch auf hunderttausende von Dateien anwenden will. (aktuell mache ich das nur mit Backups von Luks-Headern)

Gibt es eine Möglichkeit, sich ein Script zu schreiben, welches von "Datenträger A" die SHA128-Werte sämtlicher Dateien ausliest, in eine Datei schreibt und zu gegebenen Zeiten diese dann wieder zusammen mit den eigentlichen Daten gegenprüfen kann? (bzw. Ordnerweise)

Ich habe z.B. mit rsync das Problem, dass rsync zwar beim Backupen Dateien erkennt, dessen Datumsstempel verändert wurde aber nicht deren Inhalt. Jetzt gibt es die zusätzliche Option "-cI" mit der die Checksums überprüft werden. Dadurch dauern die Backups aber wesentlich länger und ich kann dennoch nicht einsehen, ob die Datei defekt gegangen ist oder absichtlich verändert wurde (im Fall: ich kopiere tausende Daten gleichzeitig, von denen hunderte absichtlich bearbeitet wurden und eine aber defekt gegangen ist, lasse ich mir überschriebene Daten anzeigen, würde diese beim Überfliegen des Logs vermutlich nicht auffallen). Bzw. gibt es ja auch den Fall, ich habe Datengräber, mit hunderttausenden Dateien, die nie mehr bearbeitet(nur gelesen) werden, dessen Datenintegrität aber dennoch regelmäßig überprüft werden soll.

Welche effiziente (möglichst Ressourcen und Zeit sparende) Lösung bietet sich an, regelmäßig die Daten auf Integrität zu prüfen? Gibt es dafür etablierte Programme oder muss ich mir selber ein Script dafür schreiben? Ich möchte möglichst das Daten vergleichen vermeiden (z.B. mit rsync) und hätte lieber direkt auf dem Datenträger eine Art Datenbank, die sämtliche SHA-Werte aller Dateien enthält, um sich selbst (speicherschonend) auf Plausibilität prüfen zu können, wenn ich gerade ein zweites Backup nicht zur Hand habe, zum Vergleichen der Daten. Ausserdem erkenne ich im Falle von 2 Backups nicht, welches Backup das defekte ist. Das geht meines Erachtens nur mit einer HASH-Liste, die ich beim ersten Erstellen des Backups anlege.

Das Problem am Bit-genauen Vergleichen von Backupdaten ist ja, dass bei beiden Backups erstmal die Hash-werte erzeugt werden müssen, um sie zu vergleichen. Wenn ich aber statt dessen von "Backup 1" alle Hashwerte in einer Datei habe, brauche ich zukünftig nur noch einmal (auf Backup 1) die Hashwerte erzeugen lassen und gegen die ursprünglich erzeugte Liste vergleichen, statt auch noch "Backup 2" zum Vergleich herziehen zu müssen und doppelte Rechenleistung reinzustecken. Jetzt mal als Beispiel. Das sind nur meine Gedankengänge bisher.

Ich finde überall tausende Möglichkeiten Backups zu erstellen. Aber nichts, was dann darüber hinaus gewährleistet, dass diese Backups auch langfristig heile bleiben.

Thomas_Do Team-Icon

Moderator
Avatar von Thomas_Do

Anmeldungsdatum:
24. November 2009

Beiträge: 8162

Du könntest z. B. mehrere Backups Deiner Daten auf verschiedenen Medien mit BorgBackup anlegen. Mithilfe des check-Befehls könntest Du dann die Integrität des Archivs prüfen.

Streifenschmerle

Avatar von Streifenschmerle

Anmeldungsdatum:
5. April 2006

Beiträge: 451

Klingt als könnten Copy-on-write-Dateisysteme wie Btrfs interessant für Dich sein. Bei Btrfs werden im Dateisystem für alle Daten und Metadaten Checksummen gespeichert; mit btrfs scrub kann auf Wunsch ein gesamtes Dateisystem überprüft werden, ob alles in Ordnung ist (insbesondere auch, ob Checksummen und Daten zueinander passen). Wenn Du Deine Daten mehrfach redundant speicherst (sprich: mind. 2 Kopien), kannst Du bei etwaigen Bitfehlern die entsprechende Datei wiederherstellen.

Viele Grüße, Jan

dingsbums

Anmeldungsdatum:
13. November 2010

Beiträge: 3337

Gibt es eine Möglichkeit, sich ein Script zu schreiben, welches von "Datenträger A" die SHA128-Werte sämtlicher Dateien ausliest, in eine Datei schreibt und zu gegebenen Zeiten diese dann wieder zusammen mit den eigentlichen Daten gegenprüfen kann? (bzw. Ordnerweise)

Falls du den Aufwand der anderen Lösungsvorschläge scheuen solltest:

Dateiliste aller Dateien inkl. Unterordnern mit sha256sum erzeugen

find /pfad/zum/ordner -type f -exec sha256sum {} + | tee sha256sums.txt

Aktuellen Zustand gegen die Dateiliste prüfen, geänderte Dateien ausgeben

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#! /bin/bash

cat sha256sums.txt | while read line;do
	datei=$(echo ${line#*' '})
	sha_saved=$(echo ${line%%' '*})
	sha_now=$(sha256sum "$datei" | cut -d ' ' -f1)
	if [ ! "$sha_now" == "$sha_saved" ];then
		echo "$datei wurde geändert"
	fi	
done

Sollte auch mit Leerzeichen in Ordner- und Dateinamen funktionieren.

Zoner

(Themenstarter)

Anmeldungsdatum:
30. August 2019

Beiträge: 120

@ dingsbums

Vielen Dank! Habe mir aus deinem Vorschlag jetzt ein schickes 200 Zeilen Script geschrieben, welches das Anlegen und Prüfen grafisch pompös vereint. (ich kann's halt nicht lassen und meine Scripte folgen mittlerweile meist einigen meiner Standards)

(habe es zum besseren Verständnis ins Deutsche übersetzt und Kommentare eingefügt, falls es jemand nutzen oder weiter bearbeiten will, ist in diesem Fall ein bisschen arg bunt geworden aber das ist wie immer Geschmackssache 😛 und in ständiger Überarbeitung)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#!/bin/bash
# V1.0, 17.03.2022

# wo soll rekursiv geprüft werden:
PRUEFVERZEICHNISS='/home/user/Documents/TEST/Testordner'

# wo soll die SHA-Liste abgelegt werden:
ARCHIVVERZEICHNISS='/home/user/Documents/TEST'
# (sollte nicht innerhalb des zu prüfenden Ordners liegen oder von der Prüfung ausgeschlossen werden, da sie sonst als "fehlerhaft" geprüft wird)

# wie soll die SHA-Liste heißen:
SHALISTE='sha256sums.txt'

# Nur weil's "schick" und übersichtlich ist:
SCRIPTTITEL="SHA-Prüfscript V1.0"



HINWEISINDIKATOR='/tmp/SHAHinweis.indikator'
# wird nur kurzeitig temporär angelegt, weil ich noch zu blöd bin, eine bessere Art von Indikator einzusetzen...


### ECHO Script Titel #########################################
echotitel () {
                echo -e "$(tput setaf 51) ░▒▓█$(tput sgr 0)$(tput setaf 232)$(tput setab 51)$(tput bold)$SCRIPTTITEL$(tput sgr 0)$(tput setaf 51)█▓▒░ $(tput sgr 0)"
                echo ""
             }


### Prüfung auf bereits vorhandene SHA-Liste ##################
shalistesuchen () {
        if      test -f $ARCHIVVERZEICHNISS/$SHALISTE
            then
                optionsabfrage2
            else
                optionsabfrage1
        fi
                }


### Optionen Auswahlabfrage ###################################
optionsabfrage1 () {
                read -p "$(tput setaf 232)$(tput setab 226)$(tput bold) Keine SHA-Liste gefunden $(tput sgr 0) $(tput setaf 226)$(tput bold)$(tput smul)N$(tput rmul)eu anlegen , $(tput smul)Quit$(tput rmul) ?$(tput sgr 0) " A
        if      [ "$A" == "n" -o "$A" == "N" ]
            then
                altesecholoeschen
                echo -e "$(tput setaf 232)$(tput setab 226)$(tput bold) Keine SHA-Liste gefunden $(tput sgr 0) $(tput setaf 226)$(tput bold)$(tput sitm)wird neu angelegt:$(tput sgr 0)"
                zeitmesser1
                                elif [ "$A" == "" ]
                                then altesecholoeschen
                                     optionsabfrage1
                                else scriptkiller
        fi
                }

optionsabfrage2 () {
                read -p "$(tput setaf 232)$(tput setab 34)$(tput bold) SHA-Liste gefunden $(tput sgr 0) $(tput setaf 34)$(tput bold)$(tput smul)P$(tput rmul)rüfen , $(tput smul)N$(tput rmul)eu anlegen , $(tput smul)Quit$(tput rmul) ?$(tput sgr 0) " A
        if      [ "$A" == "p" -o "$A" == "P" ]
            then
                altesecholoeschen
                echo -e "$(tput setaf 232)$(tput setab 34)$(tput bold) SHA-Liste gefunden $(tput sgr 0) $(tput setaf 34)$(tput bold)$(tput sitm)prüfen$(tput sgr 0)"
                pruefscript
            elif
                [ "$A" == "n" -o "$A" == "S" ]
            then
                altesecholoeschen
                echo -e "$(tput setaf 232)$(tput setab 34)$(tput bold) SHA-Liste gefunden $(tput sgr 0) $(tput setaf 34)$(tput bold)$(tput sitm)neu anlegen$(tput sgr 0)"
                zeitmesser2
                                elif [ "$A" == "" ]
                                then altesecholoeschen
                                     optionsabfrage2
                                else altesecholoeschen
                                     scriptkiller
        fi
                    }

optionsabfrage3 ()  {
                read -p "$(tput setaf 232)$(tput setab 202)$(tput bold) Differenzen gefunden $(tput sgr 0) $(tput setaf 202)$(tput bold)SHA-Liste $(tput smul)N$(tput rmul)eu anlegen , $(tput smul)Quit$(tput rmul) ?$(tput sgr 0) " A
        if      [ "$A" == "n" -o "$A" == "N" ]
            then
                altesecholoeschen
                echo -e "$(tput setaf 232)$(tput setab 202)$(tput bold) Differenzen gefunden $(tput sgr 0) $(tput setaf 202)$(tput bold)$(tput sitm)SHA-Liste neu anlegen$(tput sgr 0)"
                zeitmesser2
                                elif [ "$A" == "" ]
                                then altesecholoeschen
                                     optionsabfrage3
                                else scriptkiller
        fi
                    }

optionsabfrage4 ()  {
                read -p "$(tput setaf 34)$(tput bold)$(tput smul)P$(tput rmul)rüfen , $(tput smul)N$(tput rmul)eu anlegen , $(tput smul)Quit$(tput rmul) ?$(tput sgr 0) " A
        if      [ "$A" == "p" -o "$A" == "P" ]
            then
                altesecholoeschen
                echo -e "$(tput setaf 34)$(tput bold)$(tput sitm)prüfen$(tput sgr 0)"
                pruefscript
            elif
                [ "$A" == "n" -o "$A" == "N" ]
            then
                altesecholoeschen
                echo -e "$(tput setaf 34)$(tput bold)$(tput sitm)neu anlegen$(tput sgr 0)"
                zeitmesser1
                                elif [ "$A" == "" ]
                                then altesecholoeschen
                                     optionsabfrage4
                                else altesecholoeschen
                                     scriptkiller
        fi
                    }


###############################################################
### Prüfung der SHA Werte #####################################
###############################################################
pruefscript () {
                startshtime=$(date +%s)
                echo -e "$(tput setaf 226)prüfe Dateien mit SHA-Liste...$(tput sgr 0)                      $(tput setaf 45)$(tput bold)$(date +%H:%M) Uhr$(tput sgr 0)"
                cat $ARCHIVVERZEICHNISS/$SHALISTE | while read line;do
                data=$(echo ${line#*' '})
                sha_saved=$(echo ${line%%' '*})
                sha_now=$(sha256sum "$data" | cut -d ' ' -f1)
        if      [ ! "$sha_now" == "$sha_saved" ]
            then
                echo -e "$(tput setaf 232)$(tput setab 202)$(tput bold) SHA-Differenz: $(tput sgr 0)$(tput setaf 202) $data$(tput sgr 0)"
                touch $HINWEISINDIKATOR
        fi
                                               done
        if      test -f $HINWEISINDIKATOR
            then
                rm $HINWEISINDIKATOR
                echofertig3
            else
                echofertig1
        fi
                }


###############################################################
### SHA Werte erzeugen ########################################
###############################################################
shalistenerzeuger ()    {
                find $PRUEFVERZEICHNISS -type f -exec sha256sum {} + | tee $ARCHIVVERZEICHNISS/$SHALISTE
                        }

zeitmesser1 ()  {
        if      test -f $ARCHIVVERZEICHNISS/$SHALISTE
            then
                zeitmesser2
            else
                startshtime=$(date +%s)
                echo -e "$(tput setaf 226)schreibe neue SHA-Liste$(tput sgr 0)                             $(tput setaf 45)$(tput bold)$(date +%H:%M) Uhr$(tput sgr 0)"
                shalistenerzeuger
                endshtime=$(date +%s)
                echo -e "$(tput setaf 226)Schreiben der SHA-Liste abgeschlossen$(tput sgr 0)               $(tput setaf 45)$(tput bold)$(date +%H:%M) Uhr $(tput setaf 27)(Zeit benötigt: $((endshtime - $startshtime)) s)$(tput sgr 0)"
                echofertig2
        fi
                }

zeitmesser2 ()  {
                startshtime=$(date +%s)
                echo -e "$(tput setaf 226)überschreibe alte SHA-Liste$(tput sgr 0)                         $(tput setaf 45)$(tput bold)$(date +%H:%M) Uhr$(tput sgr 0)"
                shalistenerzeuger
                endshtime=$(date +%s)
                echo -e "$(tput setaf 226)Überschreiben der alten SHA-Liste abgeschlossen$(tput sgr 0)     $(tput setaf 45)$(tput bold)$(date +%H:%M) Uhr $(tput setaf 27)(Zeit benötigt: $((endshtime - $startshtime)) s)$(tput sgr 0)"
                echofertig2
                }


### Script Status ################################################
echofertig1 ()  {
                endshtime=$(date +%s)
                echo -e "$(tput bold)$(tput setaf 232)$(tput setab 46) FERTIG $(tput sgr 0)$(tput setaf 46)$(tput bold) Alle Dateien haben die SHA-Prüfung bestanden$(tput sgr 0)"
                echo -e "                                                    $(tput setaf 45)$(tput bold)$(date +%H:%M) Uhr $(tput setaf 27)(Zeit benötigt: $((endshtime - $startshtime)) s)$(tput sgr 0)"
                optionsabfrage4
                }

echofertig2 ()  {
        if      test -f $ARCHIVVERZEICHNISS/$SHALISTE
            then
                echo -e "$(tput bold)$(tput setaf 232)$(tput setab 34) SHA-Werte geschrieben $(tput sgr 0)"
                optionsabfrage4
            else
                echo -e "$(tput bold)$(tput setaf 232)$(tput setab 160) Keine SHA-Werte geschrieben ! (keine Schreibrechte ?)$(tput sgr 0)"
        fi
                }

echofertig3 ()  {
                endshtime=$(date +%s)
                echo -e "$(tput bold)$(tput setaf 232)$(tput setab 160) FERTIG $(tput sgr 0)$(tput setaf 160)$(tput bold) einige Dateien haben die SHA-Prüfung nicht bestanden!$(tput sgr 0)"
                echo -e "                                                    $(tput setaf 45)$(tput bold)$(date +%H:%M) Uhr $(tput setaf 27)(Zeit benötigt: $((endshtime - $startshtime)) s)$(tput sgr 0)"
                optionsabfrage3
                }


### Zeilenlöscher und Programmkiller ####################################################
scriptkiller () {
                echo -e "$(tput setaf 160)$(tput bold) Scriptfenster wird geschlossen... (Abbruch durch Nutzer)"
                sleep 2
                kill -9 $PPID
                }

altesecholoeschen () {
                echo -en "\r\033[1A\033[0K$@";
                     }


echotitel && shalistesuchen

Aber aktuell ist es dennoch etwas kantig in der Handhabung, denn ich muss immer mit der gesamten Liste arbeiten:

- Was mache ich, wenn ich die nach Backuplaufwerk-A erzeugte SHA-Liste auf Backuplaufwerk-B anwenden will? Dann muss ich ein Script schreiben, welches alle Einträge der SHA-Liste auf den Pfad von Laufwerk-B abändert? Denn wenn ich die Daten nach Laufwerk-A auch auf Laufwerk-B kopiere und dort anschließend eine eigene SHA-Liste erstelle, passen beide Laufwerks-Daten zwar zu ihren jeweiligen SHA-Listen, aber ich kann nicht sicher sein, ob es zwischen den Listen Differenzen gibt (z.B. weil beim Kopieren von A nach B Daten defekt gegangen sind und erst dann B seine eigene Liste bekommt, wo die Fehler bei Ersterstellung der Liste dann quasi mit eingepflegt werden). Die beiden Listen lassen sich ja schwer vergleichen, da die Pfade in jeder Zeile unterschiedlich sind und die Einträge vermutlich widerum unterschiedlich sortiert. (aber ich habe bisher auch noch nie intensiv mit solchen Listen gearbeitet)

- Wie kann ich kleine Veränderungen in die SHA-Liste einpflegen, ohne gleich die gesamte Liste neu erzeugen zu müssen?

Denn wenn ich wirklich sicher gehen will, wäre der aktuelle, manuelle, hanebüchene Ablauf so:

Ich erstelle meine Backups und kopiere die Daten auf Backuplaufwerk-A und B, sofern nicht bereits geschehen. Ich erzeuge eine SHA-Liste auf Laufwerk A, dann auf B, dann prüfe ich beide Laufwerke nochmal gegeneinander, um sicher zu sein, dass die kurz zuvor erzeugten SHA-Listen wirklich identisch und somit vertrauenswürdig sind. Sobald später eine Änderung in die Backups eingespielt werden soll, wird vorher das jeweilige Backup gegen die vorhandene SHA-Liste geprüft, wenn das fehlerfrei bestanden ist über RSYNC die Änderungen eingespielt, dann eine neue SHA-Liste erstellt und die Laufwerke nochmal gegeneinander geprüft um zu testen, ob auch alle SHA-Werte identisch (vertrauenswürdig) sind. Das ist brutal viel Arbeit für die Platten, wenn ich jeweils mit nur einer Liste pro Laufwerk/Partition arbeiten möchte und sich darauf jeweils zigtausende von Dateien befinden, im Terabytebereich.

Es benötigt quasi eine ART "RSYNC" für die SHA-Liste? Denn wenn ich auf dem Backup nur einen einzigen größeren Ordner verschiebe, müsste ich aktuell vorher die SHA-Liste des gesamten Backups prüfen lassen und nach dem Verschieben komplett neuanlegen. Oder das ganze vielleicht modularer gestalten, sodass jeder Ordner eine eigene SHA-Liste für die nur darin enthaltenen Dateien bekommt und später ein Script anschließend jeden Ordner prüft das eine SHA-Liste enthält?

- Auf welche Weise kann ich die Backups von 2 Laufwerken direkt gegeneinander (ohne SHA-Liste) per Prüfsumme prüfen? (angenommen die Verzeichnissstruktur ist in dem Fall exakt identisch)

Streifenschmerle schrieb:

Klingt als könnten Copy-on-write-Dateisysteme wie Btrfs interessant für Dich sein. Bei Btrfs werden im Dateisystem für alle Daten und Metadaten Checksummen gespeichert...

Theoretisch könnte ich tatsächlich für meine externen Speicher BTRFS anwenden. Verträgt sich das denn gut mit der LUKS-Verschlüsselung und den Datei-Rechten? Und ist es so easy zu handhaben wie LUKS unter ext4 (welches ich sehr leicht mit "disks" erstellen kann und sich dann in Kubuntu per GUI grafisch easy einhängen lässt) oder muss ich dann hart mit Scripten und Kommandozeile arbeiten?

san04

Anmeldungsdatum:
19. Januar 2010

Beiträge: 659

Moin Zoner,

ich bewundere die Zeit und Mühe, die du in dein Skript investiert hast.

Dein Problem ist allerdings nicht so ungewöhnlich, dass es nicht bereits gut erprobte Lösungen dafür gibt. Die sind vermutlich schneller und effizienter und es haben deutlich mehr Leute drübergeschaut, was die Gefahr für gravierende Bugs verringert. Gerade bei so einem sensiblen Thema wäre das für mich ein Grund keine eigene Lösung zu basteln.

BorgBackup wurde ja schon genannt. Ich werfe mal noch restic in den Raum. checking-integrity-and-consistency wäre hier ein Blick wert.

dingsbums

Anmeldungsdatum:
13. November 2010

Beiträge: 3337

Das ist brutal viel Arbeit für die Platten

Wenn du einen Riesenhaufen links mit einem Riesenhaufen rechts vergleichen willst, geht das nun mal nicht ohne Aufwand. Zumal wenn sich der Inhalt des "Haufens" regelmäßig ändert. Und es dürfte ziemlich egal sein, ob du das dann per eigenem Skript oder per Fertiglösung machst. Prüfsummenberechnung wird immer IO- und CPU-Last erzeugen.

Kätzchen

Avatar von Kätzchen

Anmeldungsdatum:
1. Mai 2011

Beiträge: 6036

Man kann auch Dateien so speichern oder packen, das es eine Reparaturmöglichkeit gibt. In diesem Video geht es um Windows Software, es ist aber interessant um zu kapieren wie es funktioniert: –> https://www.youtube.com/watch?v=5TsExiAsCXA

Am Ende vom Video wird auch Linux-Software genannt die diese Funktion beherrscht:

https://github.com/brenthuisman/par2deep

Zoner

(Themenstarter)

Anmeldungsdatum:
30. August 2019

Beiträge: 120

Kätzchen schrieb:

Man kann auch Dateien so speichern oder packen, das es eine Reparaturmöglichkeit gibt. In diesem Video geht es um Windows Software, es ist aber interessant um zu kapieren wie es funktioniert:

Danke, die schaue ich mir mal an (hab gerade keine gescheite Bandbreite zur Verfügung).

san04 schrieb:

Dein Problem ist allerdings nicht so ungewöhnlich, dass es nicht bereits gut erprobte Lösungen dafür gibt. Die sind vermutlich schneller und effizienter und es haben deutlich mehr Leute drübergeschaut, was die Gefahr für gravierende Bugs verringert. Gerade bei so einem sensiblen Thema wäre das für mich ein Grund keine eigene Lösung zu basteln.

BorgBackup wurde ja schon genannt. Ich werfe mal noch restic in den Raum. checking-integrity-and-consistency wäre hier ein Blick wert.

Naja, mein Script kann ich noch gut überschauen, da ist nicht viel Spielraum für Bugs. Ich erprobe immer alles sehr penibel bevor ich es erweitere und lasse mir die nötige Zeit. Und die "kompliziertere" Arbeit nimmt "rsync" ja für mich bereits ab.

Ich schreibe es lieber selber, weil ich oft Sonderwünsche habe und es dann nicht mit Features ausgestattet ist, die ich nicht brauche (und Angriffsfläche für Bugs liefern) und ich arbeite gerne nach dem KISS Prinzip, also alles so simpel wie möglich halten. Dazu gehört, so wenig zusätzliche Software wie möglich einzusetzen, bzw. mit Boardmitteln zu arbeiten. Meine Scripte sollten möglichst auf jedem Linux nativ laufen, ohne zusätzliche Installationen. Und mittels "rsync" und "sha256sum" habe ich in diesem Fall bereits alles was ich brauche.

Ausserdem lerne ich so besser mit der Shell umzugehen und Scripte zu schreiben, bzw generell das Programmieren und vor allem strukturieren größerer Scripte.

dingsbums schrieb:

Aktuellen Zustand gegen die Dateiliste prüfen, geänderte Dateien ausgeben

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#! /bin/bash

cat sha256sums.txt | while read line;do
	datei=$(echo ${line#*' '})
	sha_saved=$(echo ${line%%' '*})
	sha_now=$(sha256sum "$datei" | cut -d ' ' -f1)
	if [ ! "$sha_now" == "$sha_saved" ];then
		echo "$datei wurde geändert"
	fi	
done

Sollte auch mit Leerzeichen in Ordner- und Dateinamen funktionieren.

Mit doppelten oder mehr Leerzeichen funktioniert es nicht. 😉 Diese Daten werden korrekt in die Liste geschrieben aber bei der Prüfung nur noch teilweise ausgelesen (bis zum doppelten Leerzeichen) und entsprechend als unauffindbar bemängelt. Was aber eigentlich gut ist, so kann man diese Dateien gleich ausfindig machen und den Dateinamen korrigieren.

Kannst du mir noch einmal helfen, wie ich das Script abändern muss, damit es bei der Prüfung alle Zeilen die mit "#" beginnen ignoriert? Nachdem die Datei geschrieben wurde, wollte ich z.B. mit

1
echo -e "# bla $(date +%y%m%d)$(date +%H%M)\n$(cat /ordner/shasum.txt)" > /ordner/shasum.txt

noch ein par eigene Zeilen einfügen, damit die Datei quasi einen gescheiten Header hat, mit zusätzlichen Infos (falls man mal reingucken will, wann die Datei angelegt wurde und mit welcher Scriptversion etc.). Allerdings schlagen alle diese Zeilen dann bei der Prüfung an, statt ignoriert zu werden. Wenn ich mehr Zeit habe, werde ich mich mal tiefer mit deinem Script befassen (es vollständig verstehen) und es dann so umschreiben, dass es besser mit den eigenen Änderungen von Ordnerstrukturen umgeht, statt stumpf alles zu prüfen/neuzuschreiben. "rsync" gibt ja selber genug Daten aus, die verändert wurden und wie. Die muss ich nur gescheit mit dem SHA-Scrypt verbinden, da hab ich schon grobe Ideen.

dingsbums schrieb:

Das ist brutal viel Arbeit für die Platten

Wenn du einen Riesenhaufen links mit einem Riesenhaufen rechts vergleichen willst, geht das nun mal nicht ohne Aufwand. Zumal wenn sich der Inhalt des "Haufens" regelmäßig ändert. Und es dürfte ziemlich egal sein, ob du das dann per eigenem Skript oder per Fertiglösung machst. Prüfsummenberechnung wird immer IO- und CPU-Last erzeugen.

Für die Arbeit mit meinen USB-Sticks (mit eher kleinen Daten drauf) funktionert es bisher für mich perfekt.

Ich habe das Script mit meinem 300GB Testordner mal ausprobiert, da brauchte es ziemlich genau 20 Minuten für. Das ist für mich in Ordnung. Je größer meine Backups sind, desto seltener rühre ich diese an. Und auf den meisten meiner ganz großen Platten sind Daten die nicht so sensibel, dass ich dort eigentlich keine SHA-Prüfung brauche. Aber ich werde meine Ordnerstruktur anpassen, dass ich kleinteiliger Prüfungen durchführen kann, sodass nicht immer gleich die gesamte Platte auf einmal geprüft werden muss. Und "shamd5sum" gibts ja auch noch, was man für nicht ganz so wichtige Daten mal probieren kann.

sonstiges:

Mittlerweile ist mein Script 800 Zeilen lang. Sehr schick und mit allerlei Fehlerprüfungen gespickt, dass selbst bei grober Fehlbedienung nichts schief gehen kann. Optionen werden automtatisch deaktiviert und ausgeblendet, wenn sie nicht möglich/sinnig sind oder abgedunkelt und/oder mit einer Sicherheitsbestätigung versehen, wenn sie kritischer Natur sind (z.B. bei den Einzel-Optionen: eine SHA-Liste zu überschreiben, statt nur zu prüfen).

Und ich habe eine einwandfrei funktionierende Vollautomatik-Option eingebaut,

- die erst die SHA-Liste von Laufwerk 1 prüft, bei vom Script erkannten Änderungen stoppt das Script nach der vollständigen Prüfung und man kann dann schauen ob diese Abweichungen so stimmen, weil man diese Daten z.B. selber verändert hat und dann z.B. die Differenzen ignorieren (Script weiter machen lassen aber die Liste lassen wie sie ist) oder gleich die SHA-Liste mit den aktuellen Änderungen überschreiben, damit sie wieder auf aktuellem Stand ist (oder zurück ins Hauptmenü, wo man Einzel-Optionen auswählen kann),

- dann wird die Liste von Laufwerk 2 (das Backup) überprüft, ob die Daten seit dem letzten Mal alle immernoch heile sind,

- wenn die einwandfrei ist, automatisch "rsync" durchgeführt

- und dann die SHA-Liste (Laufwerk 2) an den neuen Stand angepasst (und nochmal geprüft, das die neue Liste auch einwandfrei funktioniert).

Das Script erkennt auch, ob bereits SHA-Listen vorhanden sind und wenn nicht, wird die Prüfung ausgelassen (weils ja nix zu prüfen gibt) und wenn noch kein Backupordner existiert, RSYNC mit anderen Befehlen die für das Erstanlegen optimiert sind ausgeführt. Fehlende Ordner werden automatisch angelegt, damit es zu keinen Fehlern kommt und das Script zeigt Anomalien bzw. "Fehler" an und was es genau tut (z.B. bei der ersten Ausführung Ordner anlegen), wenn es keine kritischen Fehler sind, behebt es diese selbstständig.

Das wende ich derzeit auf meine verschlüsselten USB-Sticks an, mit denen ich extrem viel arbeite (habe immer 2 Stück, einer als schnell einsetzbares Backup, zusätzlich zu den HDDs). Dort sind sehr sensible Daten drauf und die Dinger gelten halt nicht als sehr zuverlässig. Aber mit dem Script kann ich super bequem und auch noch recht schnell nahezu perfekt die Datenintegrität waren. Macht ein Stick Probleme würde es durch das Script sofort aufallen. Dauert auch nur wenige Sekunden bis Minuten. Ich brauche nur beide Sticks einstecken, das auf dem Stick liegende Script einmal starten, "a" (für "Automatik") und Enter drücken und dann warten bis das Fenster grün aufblinkt (bzw. seine unübersehbare "FERTIG"-Meldung zeigt und das wars.

Für Daten im niedrigen zweistelligen GB Bereich ist das bestens brauchbar.

Eine Funktion die ich in den letzten Tagen entdeckt habe. Nichts für Epileptiker aber saucool um sofort einen bestimmten Status zu erfassen, selbst wenn der Blick gerade auf einem anderen Fenster oder Bildschirm liegt.

1
printf "\e]11;green\e\\"; sleep 0.3; printf "\e]11;black\e\\"

Und wer auch Spaß an Farben hat, kann gerne das hier benutzen: (vereinfacht die Farbauswahl)

1
2
3
4
5
6
7
8
9
#!/bin/bash

echo -e "TPUT setaf"
colors=256; for (( n=0;n<colors;n++ )) do printf "$(tput setaf $n)%3s$(tput sgr0) " $n; (( (n+1)%12==0 )) && echo; done
echo -e "\n\nTPUT setab"
colors=256; for (( n=0;n<colors;n++ )) do printf "$(tput setab $n)%3s$(tput sgr0) " $n; (( (n+1)%12==0 )) && echo; done
echo -e "\n"
echo -e "$(tput setaf 4)$(tput blink)blink$(tput sgr0) $(tput setaf 4)$(tput bold)bold$(tput sgr0) $(tput setaf 4)$(tput dim)dim$(tput sgr0) $(tput setaf 4)$(tput sitm)sitm$(tput sgr0) $(tput setaf 4)$(tput rev)rev$(tput sgr0) (start standout >) $(tput setaf 4)$(tput smso)smso$(tput sgr0) $(tput setaf 4)$(tput rmso)rmso$(tput sgr0) (< end standout)"
echo -e "(start underline > ) $(tput setaf 4)$(tput smul)smul$(tput sgr0) $(tput setaf 4)$(tput rmul)rmul$(tput sgr0) (< end underline) $(tput setaf 4)$(tput invis)invis$(tput sgr0) (<invis)"

Das habe ich mir nach viel unbefriedigender Rumsucherei teilweise selbst gebastelt, damit man genau sieht, wie die Farben auf dem eigenen Monitor aussehen (da zumindest die einstelligen Zahlen wol auf den Systemen stark abweichen oder sich durch Updates verändert haben, im Netz weiß man ja oft nicht wie alt die Daten und Bilder dort sind).

[edit]

Zoner schrieb:

Kannst du mir noch einmal helfen, wie ich das Script abändern muss, damit es bei der Prüfung alle Zeilen die mit "#" beginnen ignoriert?

Habe das jetzt so gelöst:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#! /bin/bash

cat sha256sums.txt | while read line;do
if      [ ${line:0:1} != '#' ]
  then  
	datei=$(echo ${line#*' '})
	sha_saved=$(echo ${line%%' '*})
	sha_now=$(sha256sum "$datei" | cut -d ' ' -f1)
	if [ ! "$sha_now" == "$sha_saved" ];then
		echo "$datei wurde geändert"
	fi
fi
done

Damit sind für mich erstmal sämtliche Fragen erledigt.

Antworten |