How to Recover Deleted Files on Linux (TestDisk, PhotoRec, extundelete and the Snapshot You Should Have Had)

Linux has no recycle bin on the command line (tutorial 10 warned). rm -r in the wrong folder, a camera card formatted by mistake, a USB drive whose partition table vanished — the data is usually still on the disk, just unreferenced, until something overwrites it. The order of operations decides everything: stop writing, make an image, work on the image. Then the tool depends on what was lost.
Quick reference
| Situation | First | Then |
|---|---|---|
| Just deleted files on ext4 | unmount / remount read-only | extundelete or ext4magic on the device |
| Any filesystem, photos/documents | image the disk | PhotoRec carves by file signature |
| Partition gone / "unformatted" | image the disk | TestDisk finds and rewrites the partition table |
| ZFS / Btrfs with snapshots | nothing | copy from .zfs/snapshot/ (97) — done |
| Deleted from Samba share | — | Samba's recycle VFS if enabled; else as above |
| Phone/camera SD card | don't shoot more | PhotoRec on the card |
Step 0: stop writing, immediately
Every write risks the blocks you want. If it's the data drive: sudo umount /mnt/data (stop Docker stacks using it first), or sudo mount -o remount,ro /mnt/data. If it's the system disk, power down and work from a live USB (netboot.xyz, 153). Don't install the recovery tools onto the affected disk.
Step 1: image the disk
Work on a copy, never the original:
sudo apt install gddrescue -y
sudo ddrescue -d -r3 /dev/sdb /mnt/other/sdb.img /mnt/other/sdb.map
ddrescue copies everything readable and retries bad sectors (which plain dd chokes on). The image can be mounted or scanned; the original stays untouched. Needs free space equal to the drive on a different disk.
Case A: files deleted on ext4 — extundelete
Fast and keeps filenames, if the blocks haven't been reused:
sudo apt install extundelete -y
sudo extundelete /dev/sdb1 --restore-directory home/john/photos
sudo extundelete /dev/sdb1 --restore-all
Output lands in RECOVERED_FILES/ in the current folder (on another disk). Works best within minutes of the deletion on a quiet filesystem. ext4magic is the more capable sibling (-r -d out -a $(date -d "-2 hours" +%s) recovers what was deleted in the last two hours).
Case B: anything — PhotoRec
PhotoRec ignores the filesystem and carves files by their signatures (JPEG, PNG, PDF, DOCX, MP4, ZIP, hundreds more). It works on ext4, NTFS, FAT, exFAT, a formatted card, a damaged image. The cost: no filenames, no folders — thousands of f123456.jpg to sort.
sudo apt install testdisk -y # includes photorec
sudo photorec /mnt/other/sdb.img
Pick the disk/image → the partition (or Whole disk) → filesystem type (Other for anything but ext) → Free (only unallocated space, for deleted files) → an output folder on another disk. Hours for a big drive. Then sort by type and date; for photos, exiftool restores the shot date from EXIF and a quick script renames them.
Case C: the partition is gone — TestDisk
"Disk not formatted", an empty lsblk, a drive that shows as raw. TestDisk scans for partition boundaries and offers to write the table back:
sudo testdisk /dev/sdb
Create log → the disk → partition table type (usually EFI GPT or Intel) → Analyse → Quick Search. It lists the partitions it finds; P lets you browse files to confirm it's right. Write rewrites the table. Reboot or partprobe, and the filesystem mounts as before. Deep Search if Quick finds nothing.
Case D: you have snapshots
ZFS (97): ls /mnt/tank/photos/.zfs/snapshot/, copy the file back. Btrfs (170): the snapshot subvolume. Proxmox/KVM VM (81, 141): roll back. Time Machine (114) or File History (115) on the client. Thirty seconds, filenames intact, no imaging. This is why those tutorials exist — and why zfs-auto-snapshot hourly is worth the few MB.
Prevent the next one
- A trash on the command line: sudo apt install trash-cli and alias rm='trash-put' for interactive use (148), with /bin/rm when you mean it.
- Samba recycle bin: vfs objects = recycle with recycle:repository = .recycle on shares — deletions from Windows go to a hidden folder.
- Snapshots, hourly, on every data dataset.
- Backups you've restored from (159).
Troubleshooting
extundelete finds nothing. The blocks were reused, or the filesystem was mounted read-write for a while. PhotoRec.
PhotoRec output is enormous. Limit File Opt to the types you need, and Free space only.
TestDisk writes the table but the filesystem won't mount. fsck on the image (75); or the partition offset is slightly off — try the other candidates it listed.
ddrescue is stuck at a bad area. Let it finish the first pass (-n), then retry bad sectors with -r3; a failing drive (56) may need a second attempt from a cooled disk.
Wrapping up
Stop writing, ddrescue an image, then extundelete for a fresh ext4 deletion, PhotoRec for everything else, TestDisk for a lost partition. It works more often than you'd expect — and after the first time, hourly snapshots and a trash alias will make sure you never run it again.
