Feststellen, welche Downloads repariert werden müssen

ShellBeginner
Jetzt üben

Einführung

Field Notes bereitet ein gemeinschaftliches Wochenende vor. Das Ressourcenpaket enthält einen PDF-Leitfaden, Unterlagen und eine optionale, möglicherweise leere Datei mit Danksagungen. Ein Dateiname und eine plausible Größe beweisen noch keinen vollständigen Download. Bevor du etwas abrufst, erstellst du ein Inventar, das dem Organisationsteam genau zeigt, welche Dateien Aufmerksamkeit benötigen.

Du solltest die grundlegenden Bash-Argumente, Bedingungen und Schleifen aus Shell for Beginners kennen. Diese Übung erklärt SHA256, das Lesen vollständiger Zeilen und die hier verwendete Auswertung. Die Werkzeuge und die eigens erzeugten synthetischen Ressourcen sind vorbereitet. Workspace und Download Desk teilen sich einen Container; diese Übung startet unabhängig. Die geschätzte Zeit umfasst Lesen und gewöhnliche Tippfehler.

Ein verlässliches Inventar erstellen

In diesem Schritt verwandelst du eine vertrauenswürdige Prüfliste in ein Inventar des tatsächlichen lokalen Pakets, ohne eine Paketdatei zu reparieren oder neu zu schreiben.

Zuerst eine nützliche Datei ansehen

Beginne in Workspace, das für UTF-8-Text vorbereitet ist. Dein Arbeitsverzeichnis ist /home/labex/project/download-desk. pwd zeigt das aktuelle Verzeichnis. Falls ein relativer Pfad fehlt, prüfe ihn mit ls und kehre mit dem folgenden vollständigen cd-Befehl hierher zurück.

cd /home/labex/project/download-desk
ls pack

Wechsle zu Download Desk. Wähle neben Welcome guide.pdf den Link Open file. Die neue Browserseite sollte das Veranstaltungsprogramm und den Treffpunkt am östlichen Eingang zeigen. Verwende bei Bedarf die Zoomsteuerung des PDF-Readers: Ein PDF hat feste Seiten statt eines mobilen Layouts mit neu umbrechendem Text. Kehre zur Seite Download Desk zurück und wähle neben der Datei Download, um dieselben lokalen Bytes zu speichern. Wechsle danach zurück zu Workspace.

Download Desk mit Links zu den tatsächlichen lokalen Ressourcen

Verwende Open file oder Download neben Welcome guide.pdf.

Dieser Reader liefert nur tatsächlich vorhandene Dateien aus pack. Er kann keine fehlende Datei aus der Quelle ergänzen. Eine Textressource kann als Text erscheinen, die optionale leere Datei als leere Seite. Diese Beobachtungen allein beweisen noch keine korrekten Inhalte.

Eine unabhängige Referenz verwenden

Das Organisationsteam hat /opt/labex/download-pack-state/expected.sha256 getrennt vom beschreibbaren Paket bereitgestellt. Ein SHA256-Hash ist ein 64 Zeichen langer Fingerabdruck der Dateibytes. Der Vergleich mit einem unabhängigen vertrauenswürdigen Wert erkennt abweichende Bytes, auch bei Schäden mit unveränderter Dateigröße. Er bestätigt nicht die Identität des Herausgebers: Liefert ein Angreifer sowohl Datei als auch Prüfsumme, macht ihre Übereinstimmung diesen Herausgeber nicht vertrauenswürdig. Erzeuge die Referenz nicht aus den zu prüfenden Dateien neu.

cat zeigt eine Datei an, ohne sie zu verändern:

cat /opt/labex/download-pack-state/expected.sha256

Jede Zeile enthält einen 64-stelligen hexadezimalen Hash in Kleinbuchstaben, zwei Leerzeichen und den vollständigen Dateinamen. Dieser Kurs verwendet ein bereitgestelltes, lesbares, nicht leeres und mit einem Zeilenumbruch abgeschlossenes Manifest in genau diesem Format. Die Namen liegen auf einer Ebene, verwenden druckbare ASCII-Zeichen und dürfen Leerzeichen enthalten. Schrägstriche, umgekehrte Schrägstriche, CR, LF, Tabulatoren sowie die Namen . und .. gehören nicht zum Umfang. Das Paket und seine Verzeichniskette sind echte Verzeichnisse; aufgeführte Mitglieder sind gewöhnliche lokale Dateien oder fehlen. Verknüpfte Dateien, Unterverzeichnisse an einer erwarteten Dateiposition und beliebige Prüfsummenformate mit Escape-Zeichen werden nicht unterstützt. Lasse alle ursprünglichen Paketdateien und notes.txt in dieser Diagnoseübung unverändert.

sha256sum gibt den Hash und den Dateinamen aus. Doppelte Anführungszeichen halten einen Namen mit Leerzeichen als ein Argument zusammen. -- beendet die Befehlsoptionen. Das Verzeichnispräfix verhindert außerdem, dass ein mit - beginnender Basisname als Option interpretiert wird.

sha256sum -- "pack/Workshop card.txt"

Vergleiche diesen Hash mit der Referenzzeile. Sie unterscheiden sich. Die beschädigte Datei hat genauso viele Bytes wie die richtige Unterlage; ihre Größe hätte den Fehler also nicht gezeigt.

sha256sum --check liest das Manifest und prüft dessen Pfade relativ zum aktuellen Verzeichnis. Klammern führen Befehle in einer Subshell aus: Ihr cd verändert das Verzeichnis des äußeren Terminals nicht.

(cd pack && sha256sum --check /opt/labex/download-pack-state/expected.sha256)

Hier führt && die Prüfung nur aus, wenn der Wechsel nach pack erfolgreich war. Du solltest Welcome guide.pdf: OK, Workshop card.txt: FAILED, Map notes.txt: FAILED open or read und Optional credits.txt: OK sowie Warnungen sehen. Wegen der fehlenden Datei und der falschen Bytes schlägt dieser Befehl absichtlich fehl. $? enthält den nativen Exitstatus des vorherigen Befehls; lies ihn sofort, bevor ein weiterer Befehl ihn ersetzt. printf formatiert den Wert und \n beendet die Zeile.

printf 'Check exit: %s\n' "$?"

Erwartet wird Check exit: 1. Die null Byte große Danksagungsdatei ist gültig, weil ihr Hash übereinstimmt. „Nicht leer“ ist eine Anforderung an das Manifest, nicht an jede Ressource. Eine einzelne Zeile mit OK macht noch nicht das ganze Paket korrekt.

Beim Lesen von Zeilen die Namen erhalten

Das Organisationsteam braucht ein kompaktes Inventar mit einem Status und einem vollständigen Dateinamen pro Zeile, in der Reihenfolge des Manifests. Du erstellst inventory.sh, das das Manifest als $1 und das Paketverzeichnis als $2 erhält. Es ist ein eigenständiges Programm, das diese Argumente und installierte Befehle nutzt und keine benachbarten Hilfsdateien benötigt.

Lies vor dem Schreiben die verwendete Shell-Syntax:

  • while IFS= read -r line liest bei jedem Durchlauf eine vollständige Zeile. Ein leeres IFS verhindert das Abschneiden von Leerzeichen; -r verhindert die Verarbeitung umgekehrter Schrägstriche. done < "$manifest" leitet das Manifest in die Schleife um, statt Eingaben vom Terminal anzufordern.
  • ${line:0:64} entnimmt den Hash an den Zeichenpositionen 0 bis 63. ${line:66} entnimmt alles nach den beiden Trennleerzeichen. Der Dateiname wird nicht in Wörter zerlegt.
  • [ -f "$target" ] prüft, ob das unterstützte Ziel eine gewöhnliche Datei ist. Ein fehlendes Mitglied wird vor jedem Prüfsummenbefehl eingeordnet.
  • actual=$(sha256sum -- "$target") erfasst die Befehlsausgabe. ${actual%% *} entfernt den längsten passenden Endabschnitt aus einem Leerzeichen und beliebigem Folgetext; übrig bleibt der Hash. Das ist für das oben beschriebene kontrollierte Namensformat sicher.
  • printf '%s\t%s\n' schreibt zwei Werte mit einem Tabulator dazwischen und einem anschließenden Zeilenumbruch. Die Anführungszeichen erhalten jeden vollständigen Namen als ein Argument.

Das folgende Here-Dokument speichert wörtlichen Text in einem Skript. cat > inventory.sh ersetzt diese Skriptdatei; <<'BASH' endet bei einer Zeile, die nur BASH enthält. Die Anführungszeichen um die Begrenzung verhindern, dass die aktuelle Shell beim Speichern die Skriptvariablen expandiert. Die erste Zeile benennt Bash; wir führen die Datei hier ausdrücklich mit bash aus.

cat > inventory.sh <<'BASH'
#!/usr/bin/env bash
manifest=$1
pack=$2
while IFS= read -r line; do
    expected=${line:0:64}
    name=${line:66}
    target=$pack/$name
    status=MISSING
    if [ -f "$target" ]; then
        actual=$(sha256sum -- "$target")
        actual=${actual%% *}
        status=MISMATCH
        if [ "$actual" = "$expected" ]; then
            status=MATCH
        fi
    fi
    printf '%s\t%s\n' "$status" "$name"
done < "$manifest"
BASH

Starte das Skript mit der bereitgestellten Referenz und dem lokalen Paket. > leitet seine Standardausgabe in inventory.tsv um und ersetzt diesen Bericht bei jedem Aufruf. TSV steht für tabulatorgetrennte Werte. Dieser Bericht ist das Diagnoseergebnis für das Organisationsteam; er repariert keine Ressourcen.

bash inventory.sh /opt/labex/download-pack-state/expected.sha256 pack > inventory.tsv
cat inventory.tsv

Erwartet werden diese Zeilen mit jeweils einem Tabulator zwischen Status und Dateiname:

MATCH Welcome guide.pdf
MISMATCH Workshop card.txt
MISSING Map notes.txt
MATCH Optional credits.txt

Das Skript kann mit Exitstatus null enden, obwohl der Bericht MISSING enthält: Es soll klassifizieren, nicht ein vollständiges Paket behaupten. Die Richtigkeit des Berichts ergibt sich aus seinem Bezug zu den tatsächlichen Dateien und der vertrauenswürdigen Referenz. Die Prüfung testet dein Skript auch an einem anderen Paket mit anderen Namen und einer leeren Datei; genau diese Schleifenschreibweise wird nicht verlangt.

Falls du eine Skriptzeile falsch eingibst, wiederhole das vollständige Here-Dokument, um nur inventory.sh zu ersetzen, und erzeuge den Bericht erneut. Falls du versehentlich aus pack arbeitest, kehre mit dem oben gezeigten absoluten cd zurück. Lasse pack, die vertrauenswürdige Referenz und notes.txt unverändert. Ein erneuter Inventaraufruf sollte denselben Bericht ergeben, weil er das Paket nur liest. In der nächsten Übung entscheidest du anhand dieser Kategorien, was heruntergeladen werden muss.

Zusammenfassung

Du hast eine echte Ressource geöffnet, das Paket mit einer unabhängigen SHA256-Referenz verglichen und ein Bash-Inventar erstellt, das vollständige Zeilen erhält. Du hast fehlende Dateien, falsche Bytes und gültige leere Dateien unterschieden und dabei das ursprüngliche Paket unverändert gelassen. Das Inventar liefert nun für jede spätere Reparatur eine Begründung.