
🌐 Auch auf: English · Français · Español
In meinem vorherigen Artikel habe ich beschrieben, wie ich mehrere Terabyte persönlicher Daten neu sortiert und große Fotosammlungen in RAR-Archive gepackt habe.
Dadurch ist die Zahl kleiner Dateien in meinem Datenbestand drastisch geschrumpft, und die Backups laufen deutlich schneller. Sobald man sich bei der Langzeitspeicherung aber auf Archive verlässt, stellt sich ganz automatisch eine neue Frage:
Wie prüft man regelmäßig, ob wirklich alle Archivdateien noch intakt sind? 🤔
Festplatten altern, SSDs können ausfallen, und schleichende Datenkorruption (Bitrot) ist bei jahrelanger Speicherung immer zumindest theoretisch möglich.
Zum Glück bringt das RAR-Toolset eingebaute Befehle mit, um Archive zu testen, ohne sie zu entpacken. Ein Test von Hand ist schnell gemacht:
rar t archive.rarBei Hunderten oder Tausenden Archiven ist Handarbeit aber offensichtlich keine Option.
Also habe ich ein kleines Bash-Skript geschrieben, das einen Speicherbaum rekursiv durchsucht und jedes gefundene RAR-Archiv prüft.
Was das Skript macht
- Durchsucht ein Speicherverzeichnis rekursiv
- Erkennt sowohl einteilige als auch mehrteilige RAR-Archive
- Testet bei mehrteiligen Archiven nur den ersten Teil
- Führt zuerst einen schnellen Header-Scan durch
- Macht anschließend eine vollständige CRC-Prüfung
- Schreibt alle Ergebnisse in eine Logdatei
- Trägt fehlerhafte Archive in eine separate Fehlerliste ein
- Testet für mehr Tempo in parallelen Threads
- Zeigt einen Fortschrittsbalken und die voraussichtliche Restzeit (ETA) an
So lässt sich ein großer Archivbestand regelmäßig prüfen, ohne jede Datei einzeln anfassen zu müssen.
Das Skript
Hier ist das Bash-Skript, mit dem ich meine RAR-Archive aktuell prüfe.
#!/usr/bin/env bash
# ==========================================
# Configuration
# ==========================================
ERRORFILE="fehlerhafte_rars.txt"
LOGFILE="rar_test.log"
LISTFILE="$(mktemp)"
# Number of parallel jobs (adjust depending on storage speed)
THREADS=${THREADS:-4}
: > "$ERRORFILE"
: > "$LOGFILE"
echo "Searching for RAR archives..."
# ==========================================
# Build list of archives to test
# Only first volumes are included
# ==========================================
find /media/user3/MASTER/daten/ -type f \( -iname "*.rar" -o -iname "*.r[0-9][0-9]" \) | while read -r f
do
base=$(basename "$f")
# Detect modern multipart archives (.part01.rar)
if [[ "$base" =~ \.part([0-9]+)\.rar$ ]]; then
part="${BASH_REMATCH[1]}"
# Only keep the first volume
[[ "$part" != "01" && "$part" != "1" ]] && continue
echo "$f"
continue
fi
# Skip old multipart volumes (.r00 .r01 ...)
if [[ "$base" =~ \.r[0-9][0-9]$ ]]; then
continue
fi
# Normal archive or first volume of an old multipart set
echo "$f"
done | sort -u > "$LISTFILE"
TOTAL=$(wc -l < "$LISTFILE") echo "Found archives: $TOTAL" echo "Parallel jobs: $THREADS" echo START=$(date +%s) COUNT=0 # ========================================== # Function: test archive # ========================================== test_archive() { file="$1" # Fast header scan (quickly checks archive structure) if ! unrar lt -idq "$file" >/dev/null 2>&1; then
echo "$(date '+%F %T') | HEADER_ERROR | $file" >> "$LOGFILE"
echo "$(date '+%F %T') | $file" >> "$ERRORFILE"
return
fi
# Full CRC verification
if unrar t -idq "$file" >/dev/null 2>&1; then
echo "$(date '+%F %T') | OK | $file" >> "$LOGFILE"
else
echo "$(date '+%F %T') | CRC_ERROR | $file" >> "$LOGFILE"
echo "$(date '+%F %T') | $file" >> "$ERRORFILE"
fi
}
export -f test_archive
export ERRORFILE LOGFILE
# ==========================================
# Main loop with parallel execution
# ==========================================
while read -r file
do
((COUNT++))
test_archive "$file" &
# Limit number of parallel jobs
if (( $(jobs -r | wc -l) >= THREADS )); then
wait -n
fi
# Progress and ETA calculation
now=$(date +%s)
runtime=$((now-START))
avg=$((runtime/COUNT))
remain=$((TOTAL-COUNT))
eta=$((remain*avg))
printf "\rProgress: %d/%d | ETA %02d:%02d:%02d" \
"$COUNT" "$TOTAL" \
$((eta/3600)) $((eta%3600/60)) $((eta%60))
done < "$LISTFILE"
wait
echo
echo
echo "Finished."
echo "Error list: $ERRORFILE"
echo "Logfile: $LOGFILE"
So funktioniert es
Das Skript prüft in zwei Stufen:
- Header-Scan – prüft schnell die Struktur des Archivs
- Vollständiger CRC-Test – prüft den tatsächlichen Inhalt der Dateien
Fällt ein Archiv bei einem der beiden Schritte durch, landet es in einer separaten Fehlerdatei.
Weil das Skript mehrere Prüfjobs parallel ausführt, schafft es große Datenbestände viel schneller als ein sequenzieller Durchlauf.
Warum die Prüfung von Archiven wichtig ist
Langzeitspeicherung ist nie ganz ohne Risiko. Wer seine Archive regelmäßig prüft, entdeckt Probleme früh – bevor die Backups unbrauchbar werden.
Gerade bei Daten, die viele Jahre aufbewahrt werden – etwa Familienfotos oder persönliche Archive –, gehört ein regelmäßiger Integritätscheck einfach zum guten Ton.
Und natürlich … solche Aufgaben mit Bash zu automatisieren, ist schon der halbe Spaß 🙂.






