Einführung
Field Notes weiß, welche Ressourcen beschädigt sind oder fehlen. Nun braucht das Organisationsteam eine Reparaturroutine: nur diese Ressourcen abrufen, ihre Bytes mit einer unabhängigen Referenz vergleichen und jeden Ersatz erst nach bestandener Prüfung veröffentlichen. Eine Quelle kann einen HTTP-Fehler oder eine vollständig erfolgreiche HTTP-Antwort mit dem falschen Dokument liefern.
Diese Übung startet mit einem eigenen vorbereiteten Paket. Du benötigst die Kenntnisse der vorherigen Übung über SHA256, vollständige Zeilen, Befehlssubstitution und vollständige Dateinamen; Dateien aus der vorherigen VM sind nicht nötig. Workspace und Download Desk teilen sich einen Container. Das eigens erzeugte synthetische PDF und curl sind vorbereitet. Die Zeit ist eine Schätzung des Autors einschließlich Lesen und Fehlerbehebung.
Vor dem Ersetzen einen Kandidaten herunterladen
In diesem Schritt speicherst und prüfst du eine echte Unterlage in einem getrennten Übungsverzeichnis.
Beginne in Workspace, das für UTF-8-Text vorbereitet ist. Verwende diesen absoluten Pfad, wenn ein relativer Dateiname nicht gefunden wird. Mit pwd und ls pack kannst du ein falsches Verzeichnis von einem falsch geschriebenen Namen unterscheiden.
cd /home/labex/project/download-desk
Das vertrauenswürdige Manifest liegt unter /opt/labex/download-pack-state/expected.sha256. Sein Format entspricht der ersten Übung: 64 hexadezimale Kleinbuchstaben beziehungsweise Ziffern, zwei Leerzeichen und ein vollständiger Dateiname auf einer Ebene. Es wird unabhängig bereitgestellt, ist lesbar, nicht leer und endet mit einem Zeilenumbruch. Die Namen verwenden druckbares ASCII und dürfen Leerzeichen enthalten; Schrägstriche, umgekehrte Schrägstriche, CR, LF, Tabulatoren sowie . und .. als Namen gehören nicht zum Umfang. Verwende echte Verzeichnisse ohne verknüpfte Eltern. Ein erwartetes Mitglied muss fehlen oder eine gewöhnliche lokale Datei sein; Verknüpfungen und Verzeichnisobjekte werden abgewiesen. Bearbeite weder Referenz noch Quelle. Ein passender SHA256 beweist die Übereinstimmung mit dieser vertrauenswürdigen Referenz, nicht die Identität des Herausgebers.
cat /opt/labex/download-pack-state/expected.sha256
Das vorbereitete Verzeichnis trial ist für Experimente gedacht und vom pack des Organisationsteams getrennt. mktemp erstellt anhand einer mit X-Zeichen endenden Vorlage eine eindeutige leere Datei und gibt deren Pfad aus. Wenn du ihn in candidate speicherst, steht er in dieser Workspace-Sitzung weiter zur Verfügung. Bei einer neuen Verbindung können Shell-Variablen verloren gehen; beginne diese Übungssequenz dann erneut, statt den alten Wert zu erraten.
candidate=$(mktemp trial/.incoming.XXXXXX)
curl sendet eine HTTP-Anfrage. Die Optionen haben hier unterschiedliche Aufgaben:
--getsendet eine GET-Anfrage, und--data-urlencode 'name=Workshop card.txt'kodiert den Dateinamen sicher als Abfrageparameter. Anführungszeichen schützen Shell-Argumente; die URL-Kodierung behandelt Leerzeichen innerhalb der Anfrage.--failsorgt bei HTTP-Fehlern wie 503 für einen Exitstatus ungleich null. Einen falschen Inhalt bei HTTP 200 erkennt es nicht.--silent --show-errorverbirgt Fortschrittsanzeigen und erhält Fehlermeldungen.--max-time 8begrenzt die gesamte Übertragung auf acht Sekunden.--output "$candidate"schreibt nur in den temporären Kandidaten.127.0.0.1:8080ist die vorbereitete lokale Quelle im selben Container;/goodliefert die richtigen Bytes.
curl --fail --silent --show-error --get --data-urlencode 'name=Workshop card.txt' --max-time 8 --output "$candidate" http://127.0.0.1:8080/good
printf 'Download exit: %s\n' "$?"
Erwartet wird Download exit: 0. Bei einer falsch geschriebenen URL kann curl einen Verbindungsfehler oder eine HTTP-Ablehnung melden. Korrigiere die obige Adresse, entferne nur deinen aktuellen Kandidaten mit rm -- "$candidate" und wiederhole die Schritte ab mktemp. -- beendet die Optionen; der genaue Variablenwert bezeichnet dein eigenes Experiment.
Übernimm den erwarteten Hash der Unterlage aus ihrer Zeile im vertrauenswürdigen Manifest. Es ist der folgende Wert, unabhängig vom Kandidaten:
expected=a9986fb03d5ca72e42753d0ddd11dce7794b0e5a8b253dd4cd356825ca6d0583
Eine Pipe, |, verbindet die Standardausgabe eines Befehls mit der Standardeingabe des nächsten. Das folgende printf erzeugt einen Prüfsummeneintrag für deinen Kandidaten. sha256sum --check liest diesen Eintrag, und && startet mv nur nach erfolgreicher Prüfung. mv -- benennt den geprüften Kandidaten in die endgültige Übungsdatei um. Diese darf bei einer Wiederholung des Experiments ersetzt werden; die selektiven Reparaturregeln des Organisationsteams gelten für pack.
printf '%s %s\n' "$expected" "$candidate" | sha256sum --check && mv -- "$candidate" "trial/Workshop card.txt"
Erwartet wird eine auf : OK endende Zeile. Steht dort FAILED, verschiebe den Kandidaten nicht: Entferne nur diese Datei und wiederhole den korrigierten Download. Nun kannst du die geprüfte Unterlage lesen:
cat "trial/Workshop card.txt"
REPAIR DESK: EAST HALL
Du hast einen ungeprüften Download von einem endgültigen Dateinamen ferngehalten. Anschließend überträgst du diese Reihenfolge auf das gesamte Paket.
Selektiv reparieren und nach Fehlern fortsetzen
In diesem Schritt gibst du der Routine drei Argumente und prüfst sowohl ihr nützliches Ergebnis als auch ihre Schutzgrenze bei Fehlern.
Beginne in Workspace unter /home/labex/project/download-desk. Der Skriptvertrag lautet bash repair-pack.sh MANIFEST SOURCE_URL PACK_DIRECTORY. Es ist ein eigenständiges Bash-Programm mit diesen Argumenten und installierten Befehlen, ohne benachbarte Hilfsdateien. Es muss zuerst die tatsächlichen Bytes jedes Mitglieds einordnen. Ein passendes Mitglied löst keinen Download aus und behält Bytes, Modus, Eigentümer und mtime. Für die nicht zur Aufgabe gehörende Datei pack/notes.txt gilt derselbe Schutz. Nur fehlende oder abweichende Mitglieder dürfen heruntergeladen werden, pro Aufruf jeweils höchstens einmal. Eine passende leere Datei ist korrekt. Ein zweiter Aufruf bei vollständigem Paket muss null Downloadanfragen auslösen und den gesamten Paketzustand erhalten.
Jeder Kandidat liegt neben seinem Ziel und wird nach normalem Erfolg oder einem gemeldeten Fehler entfernt. Die Veröffentlichung erfolgt pro Datei: Ein geprüfter Ersatz darf bestehen bleiben, wenn ein späteres Mitglied fehlschlägt. Fehlgeschlagene oder falsche Kandidaten ersetzen ihr Ziel niemals. Das ist keine Transaktion für das ganze Paket und keine Garantie bei gleichzeitigen Schreibzugriffen, Stromausfall oder jeder denkbaren Prozessbeendigung. Verwende ausschließlich die Kurspfade und vermeide parallele Änderungen.
Parser und Hash-Extraktion verwenden die Syntax aus der vorherigen Übung. Diese zusätzlichen Elemente schützen den Ersetzungsschritt:
[ -r "$manifest" ]prüft die Lesbarkeit;[ -s "$manifest" ]verlangt ein nicht leeres Manifest.!kehrt einen Test um.||bedeutet ODER zwischen Tests oder führt nach einem fehlgeschlagenen Befehl einen Fehlerzweig aus.&&bedeutet hier UND. Geschweifte Klammern gruppieren zusammengehörige Tests ohne neue Subshell.[ -d "$pack" ]prüft ein Verzeichnis.[ -L "$target" ]erkennt auch einen Link mit fehlendem Ziel;-eprüft ein vorhandenes Ziel und-feine gewöhnliche Datei. Links und andere Objekttypen vormvabzuweisen verhindert, dass ein Quelllink verfolgt oder ein Kandidat versehentlich in ein Verzeichnis verschoben wird.temporary=beginnt mit einer leeren Variablen.trap '...' EXITregistriert die Bereinigung beim Verlassen des Skripts. Einfache Anführungszeichen verschieben die Expansion bis zur Bereinigung.-nbedeutet, dass die Variable nicht leer ist; entfernt wird nur die vom Skript selbst erstellte Datei.rm -fakzeptiert stillschweigend einen bereits entfernten Kandidaten;--beendet die Optionen.continuegeht zur nächsten Manifestzeile.exit 1meldet einen Fehler.>&2sendet eine Erklärung an die Standardfehlerausgabe statt an die normale Ausgabe. Wirdtemporarynach erfolgreichem Umbenennen geleert, kann die Bereinigung die veröffentlichte Datei nicht berühren.
Speichere dieses vollständige Skript mit dem wörtlichen Here-Dokument aus der ersten Übung:
cat > repair-pack.sh <<'BASH'
#!/usr/bin/env bash
manifest=$1
base=$2
pack=$3
if [ ! -r "$manifest" ] || [ ! -s "$manifest" ]; then
printf 'A readable nonempty trusted manifest is required.\n' >&2
exit 1
fi
if [ ! -d "$pack" ] || [ -L "$pack" ]; then
printf 'A real pack directory is required.\n' >&2
exit 1
fi
temporary=
trap 'if [ -n "$temporary" ]; then rm -f -- "$temporary"; fi' EXIT
while IFS= read -r line; do
expected=${line:0:64}
name=${line:66}
target=$pack/$name
if [ -L "$target" ] || { [ -e "$target" ] && [ ! -f "$target" ]; }; then
printf 'Expected a regular file or absent member: %s\n' "$name" >&2
exit 1
fi
if [ -f "$target" ]; then
actual=$(sha256sum -- "$target")
actual=${actual%% *}
if [ "$actual" = "$expected" ]; then
printf 'Keep: %s\n' "$name"
continue
fi
fi
temporary=$(mktemp "$pack/.repair.XXXXXX") || exit 1
if ! curl --fail --silent --show-error --get --data-urlencode "name=$name" --max-time 8 --output "$temporary" "$base"; then
printf 'Download failed: %s\n' "$name" >&2
exit 1
fi
actual=$(sha256sum -- "$temporary")
actual=${actual%% *}
if [ "$actual" != "$expected" ]; then
printf 'Checksum mismatch: %s\n' "$name" >&2
exit 1
fi
mv -- "$temporary" "$target" || exit 1
temporary=
printf 'Repaired: %s\n' "$name"
done < "$manifest"
BASH
Die Bereinigung erhält nur deinen genauen temporären Pfad und löscht keine Dateien anderer Personen. Auch ein anderer sicherer temporärer Name oder eine gleichwertige Schleife ist zulässig. Die Prüfung bewertet das Verhalten, nicht genau diese Befehlsschreibweise oder den Ausgabetext Keep:.
Eine erfolgreiche HTTP-Antwort mit falschem Inhalt testen
Der kontrollierte Endpunkt /html liefert eine HTML-Fehlerseite mit HTTP 200. Das ist eine echte Antwort und kein simulierter curl-Status. Der folgende Befehl soll fehlschlagen, ohne die vorhandene beschädigte Unterlage zu ersetzen:
bash repair-pack.sh /opt/labex/download-pack-state/expected.sha256 http://127.0.0.1:8080/html pack
printf 'Repair exit: %s\n' "$?"
Erwartet werden Repair exit: 1 und Checksum mismatch: Workshop card.txt. Das PDF war bereits korrekt und wurde übersprungen. Der falsche Kandidat wurde entfernt; ein HTTP-Erfolg allein erlaubte seine Veröffentlichung nicht. ls -a zeigt auch versteckte Namen, sodass du erkennen kannst, dass kein .repair.*-Kandidat zurückbleibt:
ls -a pack
Verwende nun die richtige Quelle. Das Skript repariert die Unterlage und die fehlende Karte und erhält dabei PDF, leere Danksagungsdatei und persönliche Notiz:
bash repair-pack.sh /opt/labex/download-pack-state/expected.sha256 http://127.0.0.1:8080/good pack
(cd pack && sha256sum --check /opt/labex/download-pack-state/expected.sha256)
Jedes aufgeführte Mitglied sollte OK anzeigen. Wechsle zu Download Desk, lade die Seite neu und öffne PDF und Karte. Die Karte nennt den östlichen Eingang. Wähle neben dem PDF Download und öffne die gespeicherte Datei im Browser-Reader. Beide Vorgänge verwenden dein lokales Paket; es gibt keinen Ersatzabruf aus der Quelle. Nutze die native Zoomsteuerung für feste PDF-Seiten. Kehre zu Workspace zurück.
Ohne erneuten Download wiederholen
Die vorbereitete Quelle schreibt für jede tatsächliche Ressourcenanfrage eine Zeile in requests.jsonl, einschließlich der Identität des Quellprozesses. Jedes Ereignis wird vor der Beobachtung vollständig in die Datei geschrieben. wc -l < FILE zählt Zeilen, indem die Datei an den Befehl umgeleitet wird; es fordert keine Ressource an. Lies den Zähler, führe die Routine erneut aus und lies ihn noch einmal:
wc -l < /opt/labex/download-pack-state/requests.jsonl
bash repair-pack.sh /opt/labex/download-pack-state/expected.sha256 http://127.0.0.1:8080/good pack
wc -l < /opt/labex/download-pack-state/requests.jsonl
Die beiden Zahlen müssen gleich sein. Alle vier Mitglieder sollten erhalten bleiben. Alles erneut herunterzuladen würde Anfragen verschwenden und könnte Modi oder Zeitstempel korrekter Dateien verändern, selbst bei identischen abschließenden Hashes.
Übertragungsfehler außerhalb des fertigen Pakets üben
mkdir -p erstellt bei Bedarf ein Experimentverzeichnis. Es setzt das Verzeichnis nicht zurück. Lasse das fertige Paket des Organisationsteams intakt:
mkdir -p trial/fault-test
Der kontrollierte Endpunkt /error liefert HTTP 503. Erwartet werden eine curl-Fehlermeldung mit 503 und ein Skriptstatus ungleich null:
bash repair-pack.sh /opt/labex/download-pack-state/expected.sha256 http://127.0.0.1:8080/error trial/fault-test
printf 'HTTP-error exit: %s\n' "$?"
Erwartet wird HTTP-error exit: 1. Der kontrollierte Endpunkt /partial schließt die Verbindung, nachdem nur ein Teil des angekündigten Antwortkörpers übertragen wurde. Erwartet werden curl-Fehler 18 zu noch fehlenden Bytes und wiederum kein veröffentlichter Kandidat:
bash repair-pack.sh /opt/labex/download-pack-state/expected.sha256 http://127.0.0.1:8080/partial trial/fault-test
printf 'Partial-transfer exit: %s\n' "$?"
Erwartet wird Partial-transfer exit: 1. Ein Verbindungsfehler, eine HTTP-Ablehnung und falsche Inhalte bei HTTP 200 sind unterschiedliche Beobachtungen; alle verhindern einen ungeprüften Ersatz. Stelle das Experiment mit demselben richtigen Endpunkt und denselben Argumenten wieder her:
bash repair-pack.sh /opt/labex/download-pack-state/expected.sha256 http://127.0.0.1:8080/good trial/fault-test
Falls Manifest- oder Verzeichnispfad falsch geschrieben sind, nennt das Skript das benötigte Objekt und endet mit einem Status ungleich null. Prüfe vor einem neuen Versuch pwd, ls und den absoluten Referenzpfad. Bei einem Syntaxfehler im gespeicherten Skript ersetze nur repair-pack.sh durch das vollständige Here-Dokument oben. Lösche nicht das Paket des Organisationsteams, um einen Tippfehler zu beheben.
Die abschließende Prüfung liest dein tatsächliches Paket und die zu erhaltenden Objekte. Sie führt dein unverändertes Skript außerdem mit isolierten Paketen mit anderen Namen und kontrollierten HTTP-Fehlern aus, darunter einem vorhandenen beschädigten Ziel und einer fehlenden, legitimen leeren Datei. Diese Anfragen stammen von deinem Skript, nicht von einem Bewertungsdownload, der fehlende Nachweise ergänzt. Eine Wiederholung der Prüfung repariert oder ersetzt deinen tatsächlichen Arbeitsstand nicht.
Zusammenfassung
Du hast einen Kandidaten heruntergeladen, vor seiner Veröffentlichung SHA256 geprüft und ein wiederverwendbares Skript zur selektiven Reparatur erstellt. Echte HTTP-Fehler, erfolgreiche Antworten mit falschem Inhalt und unterbrochene Antwortkörper gelangten nicht an endgültige Dateinamen. Korrekte Dateien und persönliche Notizen blieben erhalten, und ein zweiter Aufruf des vollständigen Pakets brauchte keine Downloads.



