Einführung
Ein Hörprobenpaket sollte alle angeforderten Ausschnitte enthalten. Scheitert eine Konvertierung, darf ein teilweise gefüllter Ordner nicht wie ein fertiges Paket aussehen. Du verbesserst ein Bash-Skript so, dass es Dateien privat vorbereitet, Fehler ehrlich meldet und erst nach erfolgreicher Konvertierung aller Dateien veröffentlicht.
Dieses Lab besitzt eigene Aufnahmen, eine beschädigte Übungskopie und ein unabhängiges älteres Paket. Es verwendet keine Dateien des vorherigen Labs. Schließe zuerst „Aus einer Hörprobe eine Stapelverarbeitung machen“ ab oder kenne dessen Anführungszeichen, FFmpeg-Optionen, Funktionen, Arrays und native Exitstatus. Außerdem verwendest du Bashs trap, um nur das temporäre Verzeichnis des Skripts aufzuräumen.
Unvollständige Konvertierungen privat vorbereiten
In diesem Schritt sorgst du dafür, dass eine fehlgeschlagene Konvertierung keinen veröffentlichten Lauf hinterlässt und bestehende Arbeit unverändert bleibt.
Beginne in Workspace, das für UTF-8-Dateinamen vorbereitet ist. Kehre mit cd hierher zurück, wenn ein relativer Pfad fehlt.
cd /home/labex/project/audio-studio
ls input library archive/previous
input enthält Übungskopien von drei Aufnahmen. In library liegen die zugelassenen intakten Originale. archive/previous ist ein älteres Hörprobenpaket, das erhalten bleiben muss; notes.txt und scratch-other gehören zu anderen Aufgaben. Ändere nur deine Skripte, die Übungskopien und neue Versuchs- oder Ausgabeverzeichnisse. Unterstützte Eingaben sind nicht versteckte reguläre Dateien direkt im Eingabeverzeichnis mit kleingeschriebenem .wav: vorzeichenbehaftetes Mono-PCM mit 16 Bit bei 22050 Hz und mindestens fünf Sekunden Länge.
Lies das Ausgangsskript mit cat. Sein exit 0 meldet auch nach einer fehlgeschlagenen Konvertierung Erfolg, und sein frühes mkdir macht ein unvollständiges Paket sichtbar.
cat batch.sh
Der folgende Test trifft absichtlich auf eine beschädigte Aufnahme. Erwarte einen FFmpeg-Fehler, der auf Invalid data found when processing input endet. Das ist ein Dateiformatfehler, kein fehlender Befehl und kein Netzwerkproblem.
bash batch.sh input trial-pack 3
printf 'Starter exit: %s\n' "$?"
Es meldet irreführend Starter exit: 0. ls trial-pack zeigt nur die erfolgreichen Konvertierungen; ein Ordner allein beweist keine Vollständigkeit.
ls trial-pack
Entferne nur diesen ausdrücklich benannten, entbehrlichen Test. rm -r löscht ein Verzeichnis samt Inhalt rekursiv; -- beendet die Verarbeitung der Optionen. Der Befehl berührt weder das ältere Paket noch Originale oder fremde Aufgaben.
rm -r -- trial-pack
Der verbesserte Vertrag verwendet bei jedem Lauf ein neues Ausgabeverzeichnis. Vorhandene Dateien, Verzeichnisse und symbolische Links werden abgewiesen, auch Links mit fehlendem Ziel. Das Elternverzeichnis der Ausgabe muss bereits vorhanden sein, und die Ausgabe muss außerhalb der Eingabe liegen. Gleichzeitige schreibende Prozesse werden nicht unterstützt. Diese Absicherung gilt für Konvertierungsfehler, nicht als Transaktionsgarantie bei Absturz oder Stromausfall.
Ein Zwischenverzeichnis nimmt Konvertierungen vor ihrer Veröffentlichung auf. mktemp -d erzeugt ein eindeutig benanntes privates Verzeichnis und ersetzt das Suffix XXXXXX. Es liegt neben der endgültigen Ausgabe, damit das abschließende Verschieben im selben Dateisystem bleibt. trap '...' EXIT räumt beim Beenden dieses Skripts auf. Einfache Anführungszeichen verschieben die Expansion von $stage bis zum Aufräumen. rm -rf -- "$stage" löscht genau dieses eigene Verzeichnis; ersetze es niemals durch Muster wie /tmp/* oder .preview.*.
Die anderen Pfadoperationen machen den Vertrag ausdrücklich. $(command) erfasst Text; || exit 2 stoppt bei einem Fehler. realpath -m normalisiert ein noch nicht vorhandenes Ziel und dirname ermittelt dessen Elternverzeichnis. Der Präfixtest case "$output/" lehnt eine Ausgabe innerhalb des Eingabeverzeichnisses ab. Anführungszeichen schützen die wörtlichen Zeichen des Eingabepräfixes, während das abschließende * einen Rest abgleicht. mv -T verschiebt das Zwischenverzeichnis auf den genauen neuen Verzeichnisnamen, statt es in ein anderes Verzeichnis einzunisten. Die vorherige Existenzprüfung ist keine Sperre für gleichzeitige Zugriffe.
Ersetze batch.sh durch die vollständige verbesserte Version. Array, Dateinamenextraktion, Anführungszeichen und FFmpeg-Argumente funktionieren wie im ersten geführten Lab.
cat > batch.sh <<'BASH'
#!/usr/bin/env bash
if [ "$#" -ne 3 ]; then printf 'Usage: batch.sh INPUT OUTPUT SECONDS\n' >&2; exit 2; fi
case "$3" in 1|2|3|4|5) seconds=$3 ;; *) printf 'Use 1 to 5 seconds\n' >&2; exit 2 ;; esac
if [ ! -d "$1" ]; then printf 'Input directory missing\n' >&2; exit 2; fi
if [ -e "$2" ] || [ -L "$2" ]; then printf 'Output already exists\n' >&2; exit 2; fi
input=$(realpath -- "$1") || exit 2
output=$(realpath -m -- "$2") || exit 2
parent=$(dirname -- "$output")
if [ ! -d "$parent" ]; then printf 'Output parent missing\n' >&2; exit 2; fi
case "$output/" in "$input/"*) printf 'Output must be outside input\n' >&2; exit 2 ;; esac
shopt -s nullglob
files=("$input"/*.wav)
if [ "${#files[@]}" -eq 0 ]; then printf 'No WAV inputs\n' >&2; exit 1; fi
stage=$(mktemp -d "$parent/.preview.XXXXXX") || exit 1
trap 'rm -rf -- "$stage"' EXIT
for source in "${files[@]}"; do
name=${source##*/}
if ! ffmpeg -nostdin -v error -i "$source" -t "$seconds" -c:a pcm_s16le "$stage/$name"; then
printf 'Could not convert: %s\n' "$name" >&2
exit 1
fi
done
if ! mv -T -- "$stage" "$output"; then exit 1; fi
printf 'Published %s previews\n' "${#files[@]}"
BASH
Versuche es erneut mit denselben beschädigten Übungseingaben. Dieser Fehler ist beabsichtigt; repariere sie noch nicht.
bash batch.sh input previews 3
printf 'Protected batch exit: %s\n' "$?"
Erwartet werden Could not convert: zz Evening.wav und Protected batch exit: 1. Der ausdrückliche Fehlerzweig stoppt den Lauf. previews darf nicht existieren, und das temporäre Zwischenverzeichnis sollte bereits entfernt sein.
ls -a zeigt auch versteckte Namen, sodass du nach zurückgelassenen .preview.-Zwischenverzeichnissen suchen kannst. scratch-other muss weiterhin sichtbar und sein Inhalt unverändert sein.
ls -a
Führe die Prüfung dieses Schritts aus. Sie testet dein unverändertes Skript in entbehrlichen Verzeichnissen; sie repariert weder deine Übungseingaben noch erzeugt sie dein tatsächliches Hörprobenpaket.
Die Übungskopie wiederherstellen und veröffentlichen
In diesem Schritt diagnostizierst du die fehlerhafte Aufnahme, stellst nur ihre erlaubte Übungskopie wieder her und veröffentlichst mit deinem Skript ein vollständiges Paket.
Beginne in Workspace. FFmpeg kann eine Aufnahme prüfen, ohne eine weitere Mediendatei zu erzeugen: -f null - wählt eine Null-Ausgabe, die dekodierte Abtastwerte verwirft. Erfolgreiches Dekodieren bestätigt lesbares Audio; eine beschädigte Datei liefert einen Status ungleich Null. Wir verwenden dies nur für die benannte Übungskopie des Kurses.
ffmpeg -nostdin -v error -i "input/zz Evening.wav" -f null -
printf 'Decode exit: %s\n' "$?"
Erwarte einen Formatfehler und einen Status ungleich Null. Die intakte Datei gleichen Namens liegt in library. cp -- kopiert dieses Original über die beschädigte Übungskopie; beide Pfade in Anführungszeichen benennen genau die Datei. Verändere nicht die Bibliothek selbst.
cp -- "library/zz Evening.wav" "input/zz Evening.wav"
ffmpeg -nostdin -v error -i "input/zz Evening.wav" -f null -
printf 'Decode exit: %s\n' "$?"
Nun wird Null erwartet. Falls der Name falsch geschrieben ist, prüfe ls library und korrigiere ihn; ein Zurücksetzen der Umgebung ist nicht nötig. Starte den vollständigen Lauf mit der wiederhergestellten Eingabe.
bash batch.sh input previews 3
Erwartet wird Published 3 previews. Wechsle zu Listening Room und lade neu. Spiele jeden Ausschnitt unter Your listening pack ab, springe darin an eine andere Stelle und lade einen herunter. Jeder Ausschnitt sollte drei Sekunden dauern und mit seiner zugehörigen Aufnahme beginnen. Die Seite liest ausschließlich previews; Löschen oder Beschädigen einer Hörprobe lässt sie nicht stillschweigend ein Bibliotheksoriginal abspielen. Kehre zu Workspace zurück.
Versuche zuletzt noch einmal die vorhandene Ausgabe zu verwenden. Diese beabsichtigte Ablehnung schützt das vollständige Paket.
bash batch.sh input previews 3
printf 'Existing output exit: %s\n' "$?"
Erwartet werden Output already exists und ein Status ungleich Null. Behalte diese Ausgabe. Für ein weiteres Paket wählst du später einen neuen Namen und eine Dauer von einer bis fünf Sekunden; das übergeordnete Verzeichnis muss vorhanden sein. Originalaufnahmen, älteres Paket, Notizen und das unabhängige Verzeichnis sollten unverändert bleiben.
Zusammenfassung
Du hast Vorbereitung und Veröffentlichung getrennt, Fehler ehrlich zurückgegeben und mit einem EXIT-Trap genau ein eigenes Zwischenverzeichnis aufgeräumt. Du hast eine beschädigte Übungsaufnahme diagnostiziert und wiederhergestellt und anschließend ein vollständiges abspielbares Paket veröffentlicht, ohne bisherige Arbeit zu verändern. Die Challenge überträgt dieselben Werkzeuge auf eine andere Sammlung.



