Operations 46 min read

How to Recover Files After an rm -rf Accident: 3 Proven Methods

This guide explains why Linux's rm command doesn't truly erase data, describes the two recovery windows (process‑held and un‑overwritten blocks), and walks through three practical recovery methods—using /proc FDs, ext4‑specific tools, and generic carving utilities—while also offering prevention strategies such as trash‑cli, snapshots, and robust backup practices.

Raymond Ops
Raymond Ops
Raymond Ops
How to Recover Files After an rm -rf Accident: 3 Proven Methods

1. Overview

The rm -rf command is the most destructive command in Linux; a typo can delete gigabytes of data instantly. Unlike Windows, Linux has no recycle bin, so deleted files disappear from the directory tree. However, the underlying file‑system mechanisms mean the data is not immediately erased, which forms the theoretical basis for recovery.

2. How Linux Deletes a File

When rm runs, the kernel performs three steps:

Remove the dentry : the name‑to‑inode mapping is deleted from the parent directory.

Decrement the inode link count ( nlink‑1). If other hard links exist, the data blocks remain.

Check the reference count : only when nlink reaches zero and no process holds an open file descriptor does the kernel free the inode and its data blocks.

Crucially, freeing the blocks only marks them as "available" in the block bitmap; the actual contents stay on disk until overwritten.

3. Two Recovery Windows

Golden window : If a process still has the file open (e.g., a log file being written), the inode and data blocks are still present. The file can be recovered 100% via /proc/<pid>/fd.

Silver window : If no process holds the file, the blocks are marked free but not yet overwritten. Recovery tools must scan the file system; success depends on how much the blocks have been overwritten.

4. Method 1 – Recover from /proc/&lt;pid&gt;/fd (Golden Window)

4.1 Principle

Linux exposes all open file descriptors under /proc/<pid>/fd. Even after the directory entry is removed, the descriptor keeps the inode and data blocks alive.

4.2 Step‑by‑Step

Find processes that still hold deleted files: lsof +L1 2>/dev/null | grep deleted The output shows PID, FD number, size, and file path.

Verify the file content (e.g., head -5 /proc/12345/fd/5).

Copy the file to a safe location:

cp /proc/12345/fd/5 /var/log/app/access.log.recovered

Restore original ownership and permissions if needed.

4.3 Batch Recovery Script

#!/bin/bash
# recover_from_proc.sh – batch recover files held by running processes
RECOVER_DIR=$1
mkdir -p "$RECOVER_DIR"
for line in $(lsof +L1 2>/dev/null | grep deleted); do
  PID=$(echo "$line" | awk '{print $2}')
  FD=$(echo "$line" | awk '{print $4}' | tr -dc '0-9')
  DEST="$RECOVER_DIR/pid_${PID}_fd_${FD}.recover"
  cp "/proc/${PID}/fd/${FD}" "$DEST"
  echo "Recovered PID=$PID FD=$FD → $DEST"
done

5. Method 2 – File‑System‑Level Recovery (ext4/Ext3)

5.1 Preparation – Stop All Writes

Immediately remount the target partition read‑only or stop services that write to it. For the root partition, boot from a Live CD/USB and mount the disk read‑only.

5.2 extundelete

extundelete parses the ext file‑system journal to locate deleted inodes.

# Install
apt install extundelete   # Debian/Ubuntu
# Recover a specific file
extundelete /dev/sda2 --restore-file data/app/config.yml
# Recover an entire directory
extundelete /dev/sda2 --restore-directory data/app/
# Recover everything (slow on large partitions)
extundelete /dev/sda2 --restore-all

Recovered files are placed in RECOVERED_FILES/. Do **not** write the output back to the same partition to avoid overwriting other deleted data.

5.3 ext4magic

ext4magic is an enhanced version of extundelete with better support for ext4 extent trees.

# Install
apt install ext4magic
# List recent deletions in the last 24 h
ext4magic /dev/sda2 -f /data/app -l
# Deep scan (‑m) for better results on large files
ext4magic /dev/sda2 -f /data/app -m -d /recovery/

5.4 Comparison

Supported FS : both support ext3/ext4.

Extent support : extundelete – basic; ext4magic – full.

Large‑file recovery : extundelete – average; ext4magic – better.

Time filtering : extundelete – after; ext4magic – after/before.

Deep scan : extundelete – none; ext4magic – yes (‑m/‑M).

6. Method 3 – Generic Data Carving (testdisk / photorec)

6.1 testdisk

Useful for recovering lost partitions or copying files from a damaged file system while preserving directory structure.

# Interactive recovery
testdisk /dev/sda
# List recoverable files (red entries) and press 'c' to copy.

6.2 photorec

Scans raw disk blocks for known file signatures; works on any file system but discards original filenames.

# Interactive mode
photorec /dev/sda2
# Choose file types to recover, output directory must be on a different partition.

6.3 Choosing Between Them

If the file system structure is intact, use testdisk (keeps names).

If the structure is corrupted or the FS is unknown, use photorec (may lose names).

7. XFS Recovery

XFS clears extent pointers on deletion, making inode‑based recovery far harder than ext4.

7.1 /proc Method (Works on XFS)

Same as the golden‑window method described in Section 4.

7.2 xfs_metadump + photorec

# Dump metadata (no actual file data)
xfs_metadump /dev/sdb1 /tmp/sdb1_meta.dump
# Then run photorec on the whole partition
photorec /dev/sdb1

7.3 xfsdump Backups

# List available backups
xfsrestore -I
# Restore a specific file
xfsrestore -f /backup/xfsdump_level0 -s data/app/config.yml /recovery/

In practice, XFS recovery success rates are low; prevention is far more important.

8. Low‑Level Recovery with debugfs (ext2/3/4)

8.1 Basic Commands

# List deleted inodes
debugfs -R "lsdel" /dev/sda2
# Show inode details
debugfs -R "stat <131073>" /dev/sda2
# Dump inode content to a file
debugfs -R "dump <131073> /tmp/recovered_file" /dev/sda2

8.2 Batch Script

#!/bin/bash
DEVICE=$1
RECOVER_DIR=$2
MIN_SIZE=${3:-1024}
mkdir -p "$RECOVER_DIR"
debugfs -R "lsdel" "$DEVICE" 2>/dev/null | \
  awk -v min=$MIN_SIZE 'NR>1 && $4>=min {print $1, $4}' | \
  while read INODE SIZE; do
    DEST="$RECOVER_DIR/inode_${INODE}_$(numfmt --to=iec-i $SIZE)"
    debugfs -R "dump <$INODE> $DEST" "$DEVICE" 2>/dev/null
    echo "Recovered inode=$INODE size=$SIZE → $DEST"
  done

8.3 Caveats

debugfs opens the file system read‑write by default; use -R for single‑command read‑only access.

On ext4, cleared extent information may lead to incomplete files.

9. Prevention Measures

9.1 trash‑cli – Turn rm into a recycle‑bin

# Install
apt install trash-cli   # Debian/Ubuntu
# Use instead of rm
trash-put config.yml
# List and restore
trash-list
trash-restore
# Empty old entries
trash-empty 30   # Remove files older than 30 days

For a system‑wide safety net, add an alias in /etc/profile.d/safe‑rm.sh: alias rm='trash-put' Use m or /bin/rm to bypass the alias when a true deletion is required.

9.2 File‑System Snapshots

LVM snapshots – create a thin snapshot before risky operations:

# Create a 10 GB snapshot
lvcreate -L 10G -s -n data_snap /dev/vg/data
# Mount read‑only and copy needed files
mount -o ro /dev/vg/data_snap /mnt/snap
cp /mnt/snap/app/config.yml /data/app/
umount /mnt/snap
# Merge (full rollback) – dangerous, discards changes after snapshot
lvconvert --merge /dev/vg/data_snap

Btrfs subvolume snapshots – one‑line read‑only snapshot:

btrfs subvolume snapshot -r /data /data/.snapshots/$(date +%Y%m%d_%H%M%S)

ZFS snapshots – instant point‑in‑time copy:

zfs snapshot pool/data@before_deploy
# Restore a single file
cp /pool/data/.zfs/snapshot/before_deploy/config.yml /pool/data/config.yml
# Full rollback
zfs rollback pool/data@before_deploy

9.3 3‑2‑1 Backup Strategy

Maintain three copies of data on two different media, with at least one copy stored off‑site.

Local fast backup – LVM/Btrfs snapshots, rsync incremental copies.

Remote encrypted backup – use restic to an S3‑compatible bucket:

restic -r s3:s3.amazonaws.com/mybucket init
restic -r s3:s3.amazonaws.com/mybucket backup /data
restic -r s3:s3.amazonaws.com/mybucket forget --keep-daily 30 --keep-weekly 12 --keep-monthly 6 --prune

Verification – schedule periodic restic check and restore drills.

9.4 Database‑Specific Protection

File‑level recovery is insufficient for databases. Use point‑in‑time recovery (PITR):

MySQL/MariaDB – enable binary logs and replay up to the desired timestamp with mysqlbinlog.

PostgreSQL – enable WAL archiving and restore to a target time using recovery_target_time.

10. Recovery Best Practices

10.1 Stop All Writes Immediately

# Remount read‑only
mount -o remount,ro /data
# Stop non‑essential services
systemctl stop nginx rsyslog cron
# Disable swap and TRIM
swapoff -a
systemctl stop fstrim.timer

10.2 Create a Disk Image Before Any Recovery Action

# Full sector‑by‑sector copy
dd if=/dev/sda2 of=/backup/sda2.img bs=4M status=progress conv=noerror,sync
# Or compressed image
dd if=/dev/sda2 bs=4M status=progress conv=noerror,sync | gzip > /backup/sda2.img.gz

All subsequent recovery work should be performed on the image, never on the original device.

10.3 Verify Recovered Files

# Size check
ls -lh recovered_file
# Type check
file recovered_file
# Content sanity (text files)
head -20 recovered_file
# Checksums (if original hash is known)
sha256sum recovered_file
# Database integrity
sqlite3 recovered.db "PRAGMA integrity_check;"

10.4 Choose the Right Method for the Situation

if process still holds file → use /proc/pid/fd (100% success)
else if FS is ext4 and journal is intact → extundelete / ext4magic (60‑80%)
else → testdisk (50‑70%) or photorec (40‑60%)

10.5 SSD vs HDD Considerations

HDDs retain data blocks until overwritten – longer recovery window.

SSDs often run TRIM, which may instantly erase freed blocks – act within seconds.

If TRIM is enabled, disable fstrim.timer and avoid writes immediately.

11. Summary Tables (Presented as Lists)

11.1 Recovery Methods Quick Reference

/proc/pid/fd – Requires the process to be alive. Success 100 %. Instant. Preserves filename. Works on any FS.

extundelete / ext4magic – For ext3/ext4 with un‑overwritten data. Success 60‑80 %. Minutes. Preserves filename. Requires journal.

testdisk – Works when FS metadata is readable. Success 50‑70 %. Minutes. Preserves filename. Multi‑FS support.

photorec – File‑signature carving. Success 40‑60 %. Hours. Filenames lost. Works on any FS.

debugfs – Manual inode dumping for ext2/3/4. Success 30‑50 %. Minutes. Filenames lost. Requires deep knowledge.

11.2 Prevention Layers (L0‑L6)

L0 – trash‑cli : Zero cost, prevents accidental rm.

L1 – immutable attribute ( chattr +i) on critical configs.

L2 – safe‑rm blacklist : blocks deletion of system paths.

L3 – filesystem snapshots (LVM, Btrfs, ZFS): seconds‑to‑minutes rollback.

L4 – local rsync backups : protects single‑node failures.

L5 – off‑site encrypted backups (restic + S3): protects site‑wide disasters.

L6 – database PITR : binlog/WAL point‑in‑time recovery.

12. References

Linux ext4 documentation – kernel source and official docs.

extundelete project page – usage and internals.

testdisk / photorec official documentation (CGSecurity).

restic backup tool – modern encrypted incremental backup.

trash‑cli GitHub – FreeDesktop.org Trash specification implementation.

Linux VFS unlink implementation – kernel source.

OpenZFS documentation – snapshots and replication.

Btrfs Wiki – subvolume and snapshot management.

Velero documentation – Kubernetes backup and restore.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

LinuxBackupSnapshotLVMExt4rmFile Recovery
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.