-> Inter-Data -> Blog -> Datenrettung von defekten Festplatten, SD-Karten, Micro-SD und SSDs unter Linux

Datenrettung von defekten Festplatten, SD-Karten, Micro-SD und SSDs unter Linux

Eine defekte Festplatte, eine SD-Karte die plötzlich nicht mehr erkannt wird oder ein USB-Stick mit wichtigen Fotos drauf – solche Situationen kennt wohl jeder. Bevor man in Panik verfällt oder teure Datenrettungsdienste beauftragt: Mit Linux und ein paar kostenlosen Tools lässt sich erstaunlich viel selbst retten. In diesem Beitrag zeige ich dir den kompletten Weg von der ersten Diagnose bis zur sortierten Wiederherstellung.

Wichtig: Ruhe bewahren und nichts überschreiben

Der größte Fehler bei der Datenrettung ist Hektik. Jeder Schreibvorgang auf dem defekten Datenträger kann Daten unwiderruflich zerstören. Deshalb gilt:

  • Nicht versuchen, den Datenträger zu reparieren (kein fsck, kein chkdsk).
  • Nicht neue Daten draufschreiben.
  • Nicht das Betriebssystem davon starten lassen.

Der erste und wichtigste Schritt ist immer: ein bitgenaues Abbild (Image) des Datenträgers erstellen. Damit arbeiten wir dann in Ruhe weiter, und der defekte Datenträger kann danach in die Schublade wandern.

Voraussetzungen

Für die Datenrettung brauchen wir folgende Pakete. Unter Linux Mint, Ubuntu oder Debian installierst du sie mit:

sudo apt update
sudo apt install gddrescue testdisk imagemagick

Das Paket gddrescue enthält das Tool ddrescue, mit dem wir das Disk-Image erstellen. In testdisk steckt auch photorec, das die eigentliche Dateiwiederherstellung übernimmt. imagemagick nutzen wir später, um echte Fotos von Windows-Icons und Thumbnails zu unterscheiden.

Hinweis: Das Paket heißt gddrescue (GNU ddrescue) und nicht ddrescue – das sind zwei verschiedene Programme. Achte darauf, das richtige zu installieren.

Schritt 1: Datenträger identifizieren mit fdisk

Schließe den defekten Datenträger an (USB-Adapter, Kartenleser, etc.) und finde heraus, welches Device er bekommen hat:

sudo fdisk -l

Die Ausgabe zeigt alle angeschlossenen Datenträger mit ihren Partitionen. Das sieht dann ungefähr so aus:

Disk /dev/sda: 238,47 GiB, 256060514304 bytes, 500118192 sectors
...

Disk /dev/sdb: 298,09 GiB, 320072933376 bytes, 625142448 sectors
Disk model: My Passport 0740
Units: sectors of 1 * 512 = 512 bytes

Device     Boot  Start       End   Sectors   Size Id Type
/dev/sdb1  *      2048   1026047   1024000   500M  7 HPFS/NTFS/exFAT
/dev/sdb2      1026048 625141759 624115712 297,6G  7 HPFS/NTFS/exFAT

In diesem Beispiel ist /dev/sda die interne SSD und /dev/sdb die externe USB-Festplatte, die wir retten wollen. Merke dir den Devicenamen – im weiteren Verlauf verwende ich /dev/sdb als Beispiel. Pass das an deinen Fall an.

Alternativ kannst du auch lsblk verwenden, das zeigt die Zuordnung etwas übersichtlicher:

lsblk -o NAME,SIZE,FSTYPE,LABEL,MOUNTPOINT

Vorsicht: Verwechsle niemals den defekten Datenträger mit deiner Systemplatte. Ein ddrescue in die falsche Richtung und dein laufendes System ist weg. Lieber dreimal prüfen.

Schritt 2: Disk-Image erstellen mit ddrescue

Jetzt erstellen wir ein bitgenaues Abbild. Dafür brauchst du genug freien Speicherplatz auf einer anderen Platte – mindestens so viel wie der defekte Datenträger groß ist.

sudo ddrescue -d -r3 /dev/sdb /mytmp/hdd-rescue.img /mytmp/hdd-rescue.log

Die Parameter im Einzelnen:

  • -d – Direct Access, umgeht den Kernel-Cache. Sinnvoll bei defekter Hardware.
  • -r3 – Versucht fehlerhafte Sektoren bis zu 3 Mal erneut zu lesen.
  • /dev/sdb – Der Quelldatenträger (das ganze Device, nicht einzelne Partitionen).
  • /mytmp/hdd-rescue.img – Zieldatei für das Image.
  • /mytmp/hdd-rescue.log – Logdatei, die den Fortschritt speichert.

Die Logdatei ist extrem wichtig: Falls ddrescue unterbrochen wird (Kabel rausgezogen, Rechner abgestürzt), kannst du den Vorgang einfach mit dem identischen Befehl fortsetzen. Das Tool liest dann nur die noch fehlenden Bereiche nach.

Bei einer 320 GB Platte kann das je nach Zustand zwischen einer Stunde und mehreren Tagen dauern. Defekte Sektoren bremsen den Vorgang stark aus. Die Fortschrittsanzeige zeigt dir, wie viele Fehler aufgetreten sind:

GNU ddrescue 1.27
Press Ctrl-C to interrupt
     ipos:  156372 MB, non-trimmed:    1536 B,  current rate:  33554 kB/s
     opos:  156372 MB, non-scraped:        0 B,  average rate:  44142 kB/s
non-tried:  163700 MB,  bad-sector:        0 B,    error rate:       0 B/s
  rescued:  156372 MB,   bad areas:        0,        run time:  59m  2s
pct rescued:   48.85%, read errors:        0,  remaining time:  1h  1m

Sonderfall SD-Karten und Micro-SD

Bei SD-Karten ist der Vorgang identisch. Die Karte taucht meist als /dev/mmcblk0 auf (oder bei USB-Kartenlesern als /dev/sdb o.ä.):

sudo ddrescue -d -r3 /dev/mmcblk0 /mytmp/sd-rescue.img /mytmp/sd-rescue.log

SD-Karten haben oft das Problem, dass sie irgendwann komplett den Dienst verweigern. Wenn die Karte schon beim Einstecken nicht mehr erkannt wird (dmesg zeigt Fehler), hilft leider auch ddrescue nicht mehr. In dem Fall bleibt nur ein professioneller Datenrettungsdienst, der den Flash-Chip direkt ausliest.

Schritt 3: Dateien wiederherstellen mit PhotoRec

Jetzt haben wir ein Image und können in Ruhe damit arbeiten. Der defekte Datenträger ist ab jetzt nicht mehr nötig.

PhotoRec durchsucht das Image sektorweise nach bekannten Dateiheadern – es kann also auch Dateien finden, deren Verzeichniseinträge längst überschrieben sind. Das Ergebnis sind Ordner voller Dateien mit kryptischen Namen wie f0012345.jpg. Die Originalnamen sind in der Regel verloren.

Manuell mit PhotoRec

Wer es einmal manuell ausprobieren will:

photorec /d /mytmp/output /cmd /mytmp/hdd-rescue.img wholespace,search

PhotoRec legt im Zielverzeichnis mehrere Unterordner an (recup_dir.1, recup_dir.2, …) und füllt sie mit den gefundenen Dateien. Je nach Imagegröße können das tausende Dateien sein – ein ziemliches Chaos.

Automatisiert mit dem Recovery-Script

Damit man nicht stundenlang manuell sortiert, habe ich ein Bash-Script geschrieben, das den kompletten Ablauf automatisiert: PhotoRec laufen lassen, die gefundenen Dateien nach Typ sortieren und dabei mit ImageMagick echte Fotos von Icons und Thumbnails unterscheiden.

Das Script recover_and_sort.sh wird so aufgerufen:

chmod +x recover_and_sort.sh
./recover_and_sort.sh /mytmp/hdd-rescue.img /mytmp/output

Standardmäßig wird im Modus wholespace gescannt, also die gesamte Partition – das bringt die meisten Ergebnisse. Optional kann man freespace als dritten Parameter übergeben, falls das Dateisystem noch intakt ist und man nur gelöschte Dateien sucht.

Hier das komplette Script:

#!/usr/bin/env bash
set -euo pipefail

# ==========================================================
# recover_and_sort.sh
# Datenrettung aus Disk-Images mit PhotoRec + intelligente Sortierung
#
# Usage:
#   ./recover_and_sort.sh <IMAGE> <OUTPUT_DIR> [freespace|wholespace]
#
# Beispiel:
#   ./recover_and_sort.sh hdd-rescue.img /mytmp/output freespace
#
# Benötigt: testdisk (photorec), imagemagick (identify), coreutils
# ==========================================================

IMAGE="${1:-}"
OUT_BASE="${2:-}"
SCAN_MODE="${3:-wholespace}"

# --- Argumente prüfen ---
if [[ -z "$IMAGE" || -z "$OUT_BASE" ]]; then
  echo "Usage: $0 <IMAGE> <OUTPUT_DIR> [freespace|wholespace]"
  exit 1
fi
if [[ ! -f "$IMAGE" ]]; then
  echo "ERROR: Image nicht gefunden: $IMAGE"
  exit 1
fi
if [[ "$SCAN_MODE" != "freespace" && "$SCAN_MODE" != "wholespace" ]]; then
  echo "ERROR: SCAN_MODE muss 'freespace' oder 'wholespace' sein"
  exit 1
fi

# --- Abhängigkeiten prüfen ---
need_cmd() {
  command -v "$1" >/dev/null 2>&1 || {
    echo "ERROR: '$1' fehlt. Installiere z.B. 'sudo apt install $2'"
    exit 1
  }
}
need_cmd testdisk   testdisk
need_cmd photorec   testdisk
need_cmd identify   imagemagick
need_cmd awk        gawk
need_cmd readlink   coreutils

mkdir -p "$OUT_BASE"
OUT_BASE="$(readlink -f "$OUT_BASE")"
IMAGE_ABS="$(readlink -f "$IMAGE")"

# ==========================================================
# 1) Partitionen aus Image ermitteln
# ==========================================================
PART_LOG="$OUT_BASE/testdisk_partitions.log"
echo "=== Analysiere Partitionen in: $IMAGE_ABS"
testdisk -l "$IMAGE_ABS" 2>&1 | tee "$PART_LOG" >/dev/null

# Partition-Nummern extrahieren (Zeilen, die mit Zahl beginnen)
mapfile -t PARTS < <(awk '/^[[:space:]]*[0-9]+[[:space:]]/ {print $1}' \
  "$PART_LOG" | sort -n | uniq)

if [[ "${#PARTS[@]}" -eq 0 ]]; then
  echo "ERROR: Keine Partitionen gefunden. Siehe: $PART_LOG"
  exit 1
fi

echo "Gefundene Partitionen: ${PARTS[*]}"
echo "Scan-Modus: $SCAN_MODE"
echo

# ==========================================================
# 2) PhotoRec scripted pro Partition
# ==========================================================
RECOVER_ROOT="$OUT_BASE/recovered_raw"
mkdir -p "$RECOVER_ROOT"

for p in "${PARTS[@]}"; do
  PART_DIR="$RECOVER_ROOT/part_$p"
  mkdir -p "$PART_DIR"

  echo "=== PhotoRec: Partition $p -> $PART_DIR"
  photorec /log /d "$PART_DIR" /cmd "$IMAGE_ABS" \
    "${SCAN_MODE},${p},search" || true
done

echo
echo "✅ Recovery abgeschlossen. Rohdaten: $RECOVER_ROOT"
echo

# ==========================================================
# 3) Sortieren: nur relevante Dateien, echte Fotos erkennen
# ==========================================================
SORT_DIR="$OUT_BASE/SORTIERT"
mkdir -p "$SORT_DIR"/{Bilder,Dokumente,Tabellen,Praesentationen,PDFs,Texte}

# --- Foto-Filter-Parameter ---
MIN_IMAGE_BYTES=$((300 * 1024))   # 300 KB Mindestgröße
MIN_IMAGE_WIDTH=640               # Mindestbreite in Pixel
MIN_IMAGE_HEIGHT=480              # Mindesthöhe in Pixel
MIN_IMAGE_PIXELS=$((640 * 480))   # ~307.200 Pixel Mindestfläche

# Statistik-Zähler
STAT_TOTAL=0
STAT_FOTOS_OK=0
STAT_FOTOS_SKIP=0
STAT_DOCS=0

copy_to() {
  local file="$1" target="$2"
  mkdir -p "$SORT_DIR/$target"
  cp -n -- "$file" "$SORT_DIR/$target/" 2>/dev/null || true
}

# is_real_photo: Prüft ob ein Bild ein echtes Foto ist
# (nicht Icon/Thumbnail)
# Kriterien:
#   1. Dateigröße >= MIN_IMAGE_BYTES
#   2. Breite >= MIN_IMAGE_WIDTH UND Höhe >= MIN_IMAGE_HEIGHT
#   3. Gesamtpixel >= MIN_IMAGE_PIXELS (fängt 256x256 Icons ab)
#   4. Kein ICO-Format (Windows-Icons werden manchmal als
#      .png recovered)
is_real_photo() {
  local file="$1"

  # Dateigröße prüfen
  local size
  size="$(stat -c%s "$file" 2>/dev/null || echo 0)"
  if [[ "$size" -lt "$MIN_IMAGE_BYTES" ]]; then
    return 1
  fi

  # ImageMagick identify: Format, Breite, Höhe auslesen
  local info
  if ! info="$(identify -format '%m %w %h' "$file" \
    2>/dev/null)"; then
    return 1
  fi

  local fmt width height
  read -r fmt width height <<< "$info"

  # ICO-Format aussortieren (Windows-Icons)
  if [[ "$fmt" == "ICO" || "$fmt" == "CUR" ]]; then
    return 1
  fi

  # BMP unter 100KB sind oft System-Icons
  if [[ "$fmt" == "BMP" && "$size" -lt $((100 * 1024)) ]]; then
    return 1
  fi

  # Mindestauflösung prüfen
  if [[ "$width" -lt "$MIN_IMAGE_WIDTH" \
     || "$height" -lt "$MIN_IMAGE_HEIGHT" ]]; then
    return 1
  fi

  # Gesamtpixel prüfen (fängt quadratische Icons ab)
  local pixels=$(( width * height ))
  if [[ "$pixels" -lt "$MIN_IMAGE_PIXELS" ]]; then
    return 1
  fi

  return 0
}

echo "=== Sortiere Dateien aus recovered_raw/ ==="
echo "    Foto-Filter: min ${MIN_IMAGE_BYTES} Bytes," \
     "min ${MIN_IMAGE_WIDTH}x${MIN_IMAGE_HEIGHT} px"
echo

while IFS= read -r -d '' f; do
  STAT_TOTAL=$(( STAT_TOTAL + 1 ))
  ext="${f##*.}"; ext="${ext,,}"

  case "$ext" in
    jpg|jpeg|png|tif|tiff|bmp|heic|nef|cr2|arw|dng|raw|webp)
      if is_real_photo "$f"; then
        copy_to "$f" "Bilder"
        STAT_FOTOS_OK=$(( STAT_FOTOS_OK + 1 ))
      else
        STAT_FOTOS_SKIP=$(( STAT_FOTOS_SKIP + 1 ))
      fi
      ;;
    pdf)          copy_to "$f" "PDFs";             STAT_DOCS=$(( STAT_DOCS + 1 )) ;;
    doc|docx|odt|rtf) copy_to "$f" "Dokumente";   STAT_DOCS=$(( STAT_DOCS + 1 )) ;;
    xls|xlsx|ods|csv) copy_to "$f" "Tabellen";    STAT_DOCS=$(( STAT_DOCS + 1 )) ;;
    ppt|pptx|odp) copy_to "$f" "Praesentationen"; STAT_DOCS=$(( STAT_DOCS + 1 )) ;;
    txt|md)       copy_to "$f" "Texte";            STAT_DOCS=$(( STAT_DOCS + 1 )) ;;
    *) ;;
  esac
done < <(find "$RECOVER_ROOT" -type f -print0)

echo

# Speicherbedarf berechnen
SIZE_RAW="$(du -sh "$RECOVER_ROOT" 2>/dev/null | cut -f1)"
SIZE_SORTED="$(du -sh "$SORT_DIR" 2>/dev/null | cut -f1)"
SIZE_BILDER="$(du -sh "$SORT_DIR/Bilder" 2>/dev/null | cut -f1 || echo "0")"
SIZE_DOCS="$(du -sh "$SORT_DIR/Dokumente" 2>/dev/null | cut -f1 || echo "0")"
SIZE_PDFS="$(du -sh "$SORT_DIR/PDFs" 2>/dev/null | cut -f1 || echo "0")"
SIZE_TABELLEN="$(du -sh "$SORT_DIR/Tabellen" 2>/dev/null | cut -f1 || echo "0")"
SIZE_PRAES="$(du -sh "$SORT_DIR/Praesentationen" 2>/dev/null | cut -f1 || echo "0")"
SIZE_TEXTE="$(du -sh "$SORT_DIR/Texte" 2>/dev/null | cut -f1 || echo "0")"

echo "============================================"
echo "✅ Sortierung fertig: $SORT_DIR"
echo "--------------------------------------------"
echo "   Dateien gesamt gefunden:   $STAT_TOTAL"
echo "   Echte Fotos übernommen:    $STAT_FOTOS_OK"
echo "   Icons/Thumbs übersprungen: $STAT_FOTOS_SKIP"
echo "   Dokumente/Tabellen/etc.:   $STAT_DOCS"
echo "--------------------------------------------"
echo "   Speicherbedarf:"
echo "     Rohdaten (gesamt):       $SIZE_RAW"
echo "     Sortiert (gesamt):       $SIZE_SORTED"
echo "       ├─ Bilder:             $SIZE_BILDER"
echo "       ├─ Dokumente:          $SIZE_DOCS"
echo "       ├─ PDFs:               $SIZE_PDFS"
echo "       ├─ Tabellen:           $SIZE_TABELLEN"
echo "       ├─ Präsentationen:     $SIZE_PRAES"
echo "       └─ Texte:              $SIZE_TEXTE"
echo "--------------------------------------------"
echo "   Rohdaten bleiben unter:    $RECOVER_ROOT"
echo "============================================"

Das Script erledigt drei Dinge:

  1. Partitionen erkennen – Es liest mit testdisk die Partitionsstruktur aus dem Image.
  2. PhotoRec pro Partition – Jede Partition wird einzeln gescannt und die Ergebnisse landen in separaten Ordnern.
  3. Sortierung – Alle gefundenen Dateien werden nach Kategorien in Unterordner einsortiert: Bilder, Dokumente, PDFs, Tabellen, Präsentationen und Textdateien. Bilddateien durchlaufen dabei einen Filter mit ImageMagick: Nur Dateien mit einer Auflösung über 640×480 Pixel und mindestens 300 KB Größe werden als echte Fotos übernommen. Windows-Icons, Thumbnails und Systemgrafiken werden so automatisch aussortiert.

Am Ende gibt das Script eine Zusammenfassung aus:

============================================
✅ Sortierung fertig: /mytmp/output/SORTIERT
--------------------------------------------
   Dateien gesamt gefunden:   4832
   Echte Fotos übernommen:    1247
   Icons/Thumbs übersprungen: 3021
   Dokumente/Tabellen/etc.:   564
--------------------------------------------
   Speicherbedarf:
     Rohdaten (gesamt):       12G
     Sortiert (gesamt):       2,4G
       ├─ Bilder:             1,8G
       ├─ Dokumente:          312M
       ├─ PDFs:               187M
       ├─ Tabellen:           45M
       ├─ Präsentationen:     82M
       └─ Texte:              1,2M
--------------------------------------------
   Rohdaten bleiben unter:    /mytmp/output/recovered_raw
============================================

Die Rohdaten aus den recup_dir.*-Ordnern bleiben erhalten, falls man später noch einmal manuell nachschauen möchte. Löschen kann man sie, sobald man mit dem Ergebnis zufrieden ist.

Tipps aus der Praxis

Zielplatte vorher prüfen. Nichts ist ärgerlicher als ein abgebrochener Rettungsvorgang, weil die Zielplatte voll ist. Prüfe vorher mit df -h, ob genug Platz da ist. Faustregel: Doppelt so viel wie der Quelldatenträger groß ist (Image + wiederhergestellte Dateien).

Image immer auf eine andere physische Platte schreiben. Nie auf den selben Datenträger, und nach Möglichkeit nicht auf dieselbe physische Platte, auch wenn es eine andere Partition ist.

Bei mechanischen Festplatten auf Geräusche achten. Klackernde oder schleifende Geräusche deuten auf einen Headcrash hin. In dem Fall: Sofort ausschalten und zu einem professionellen Datenrettungsdienst gehen. Jede weitere Minute kann die Platten-Oberfläche weiter beschädigen.

ddrescue in Etappen laufen lassen. Bei stark defekten Platten kann es sinnvoll sein, ddrescue mehrfach mit verschiedenen Parametern laufen zu lassen. Zuerst einen schnellen Durchlauf ohne Retries (-r0), um die lesbaren Bereiche zu sichern. Dann einen zweiten Lauf mit Retries (-r3) für die schwierigen Stellen. Die Logdatei sorgt dafür, dass nichts doppelt gelesen wird.

Gelöschte Dateien: Zeit ist der Feind. Je länger ein Datenträger nach dem Löschen weiter benutzt wird, desto mehr wird überschrieben. Am besten sofort ein Image ziehen und erst danach normal weiterarbeiten.

Fazit

Datenrettung unter Linux ist kein Hexenwerk. Mit ddrescue und photorec hat man zwei mächtige und kostenlose Werkzeuge, die auch bei stark beschädigten Datenträgern noch erstaunlich viel herausholen können. Der wichtigste Grundsatz bleibt: Erst ein Image erstellen, dann in Ruhe wiederherstellen. Und wer seine Daten regelmäßig sichert, muss diesen Artikel hoffentlich nie in der Praxis anwenden.