-
-
Save Changaco/45f8d171027ea2655d74 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# btrfs-undelete | |
# Copyright (C) 2013 Jörg Walter <info@syntax-k.de> | |
# This program is free software; you can redistribute it and/or modify it under | |
# the term of the GNU General Public License as published by the Free Software | |
# Foundation; either version 2 of the License, or any later version. | |
if [ ! -b "$1" -o -z "$2" -o -z "$3" ]; then | |
echo "Usage: $0 <dev> <file/dir> <dest>" 1>&2 | |
echo | |
echo "This program tries to recover the most recent version of the" | |
echo "given file or directory (recursively)" | |
echo | |
echo "<dev> must not be mounted, otherwise this program may appear" | |
echo "to work but find nothing." | |
echo | |
echo "<file/dir> must be specified relative to the filesystem root," | |
echo "obviously. It may contain * and ? as wildcards, but in that" | |
echo "case, empty files might be 'recovered'. If <file/dir> is a" | |
echo "single file name, this program tries to recover the most" | |
echo "recent non-empty version of the file." | |
echo | |
echo "<dest> must be a writable directory with enough free space" | |
echo "to hold the files you're trying to restore." | |
exit 1 | |
fi | |
dev="$1" | |
file="$2" | |
file="${file#/}" | |
file="${file%/}" | |
regex="${file//\\/\\\\}" | |
# quote regex special characters | |
regex="${regex//./\.}" | |
regex="${regex//+/\+}" | |
regex="${regex//|/\|}" | |
regex="${regex//(/\(}" | |
regex="${regex//)/\)}" | |
regex="${regex//\[/\[}" | |
regex="${regex//]/\]}" | |
regex="${regex//\{/\{}" | |
regex="${regex//\}/\}}" | |
# treat shell wildcards specially | |
regex="${regex//\*/.*}" | |
regex="${regex//\?/.}" | |
# extract number of slashes in order to get correct number of closing parens | |
slashes="${regex//[^\/]/}" | |
# build final regex | |
regex="^/(|${regex//\//(|/}(|/.*${slashes//?/)}))\$" | |
roots="$(mktemp --tmpdir btrfs-undelete.roots.XXXXX)" | |
out="$(mktemp --tmpdir="$3" -d btrfs-undelete.XXXXX)" | |
cd $out | |
trap "rm $roots" EXIT | |
trap "rm -r $out &> /dev/null; exit 1" SIGINT | |
echo -ne "Searching roots..." | |
btrfs-find-root -a "$dev" 2>&1 \ | |
| grep ^Well \ | |
| sed -r -e 's/Well block ([0-9]+).*/\1/' \ | |
| sort -rn >$roots || exit 1 | |
echo | |
i=0 | |
max="$(wc -l <$roots)" | |
while read id; do | |
((i+=1)) | |
echo -e "Trying root $id... ($i/$max)" | |
btrfs restore -t $id --path-regex "$regex" "$dev" . &>/dev/null | |
if [ "$?" = 0 ]; then | |
found=$(find . -type f ! -size 0c | wc -l) | |
if [ $found -gt 0 ]; then | |
echo "Recovered $found non-empty file(s) into $out" | |
exit 0 | |
fi | |
find . -type f -size 0c -exec echo "Found {} but it's empty" \; -delete | |
fi | |
done <$roots | |
rm -r $out | |
echo "Didn't find '$file'" | |
exit 1 |
Can you write some examples with different <file/dir>
formats? wildcards, etc? No matter what format I enter, it says "Didn't find ..."
OH IT NEEDS TO BE RUN AS ROOT using sudo
. Then it says
...
Trying root 14769717477376... (192/213)
Trying root 14769717379072... (193/213)
Trying root 14769716805632... (194/213)
Trying root 14769716510720... (195/213)
...
But still doesn't find anything, even with a very broad search like sudo ./btrfs-undelete /dev/sdc "/Foldername/*" ~/restore
which is a folder that definitely still exists on that volume...
Edit: Nevermind it somehow re-mounted itself, so it wasn't working even though it looked like it was. The above command does work! Yayyyy
Does this script really work unattended? Because I executed the restore command manually and I needed to confirm a "looping a lot" question:
btrfs restore -i /dev/nvme1n1p1 /mnt/disk2/nvme1n1p1_restore
No valid Btrfs found on /dev/nvme1n1p1
Could not open root, trying backup super
We seem to be looping a lot on /mnt/disk2/nvme1n1p1_restore/domains/Win10/vdisk1.img, do you want to keep going on ? (y/N/a)
I was not able to find a flag which allowed unattended execution?!
@mgutt, the restore
command you did is not exactly the same as the one used in the script, anyway if you want to avoid answering y
indefinitely you can do that:
yes | btrfs restore -i /dev/nvme1n1p1 /mnt/disk2/nvme1n1p1_restore
I know. Its only a hint. Maybe the same can happen for the btrfs-undelete script, so it become stuck?!
Regarding your piping idea. I think "a" for "all" would be better. But does it return "a" + "enter", which is needed? (I can't test it anymore)
PS
I hit "N" because the file was not important for me. Anyhow, it was restored ^^
To always answer a
you can do:
yes a | btrfs restore -i /dev/nvme1n1p1 /mnt/disk2/nvme1n1p1_restore
Anyhow, it was restored ^^
Maybe it's incomplete?
(Lubuntu 18.04x64)
hello, I would like to have some pressision on your script
To execute it, I have to copy and paste it into a text editor
saved it under the .sh extension and make it executable right?
and
I have rescement I deleted by mistake a very important folder on my secondary hard drive (/ dev / sda3) an HDD
The file contained only zip that I want to receive
/dev/sda3 = /mnt/38b05da3-7068-45b9-bc0a-0b944f15487f
A friend recommended me the following monate options to make the disk read alone thus avoiding the old data, for limiting the loss.
nosuid,nodev,nofail,x-gvfs-show,noatime,nodiratime,ro
that right for you ?
I plugged in an external hard drive, because my systeme ssd are prety small
/dev/sdc1 = /media/dae-rog/data-backup
My question is, are your tools like?
Where is it asking for data once executed?
Or do I manually be edited?
Dae#5125 on discord
Thank you
Thank you so much! This saved me 12 days.
amazing works! saved my monthes!
When working with subvolumes make sure to include subvolume data. For example, to extract tree of files from @data
subvolume and user /home/accident
use command:
btrfs-undelete /dev/mapper/container '@data/home/accident' /tmp/extraction-location
This will include all fines under /home/accident
.
" must not be mounted, otherwise this program may appear
to work but find nothing."
can I unmount dev on a running system?
oh I get it. please change the wording of dev to source device
can this also find the next most recent deleted file? I think I got most of what I wanted back except for a few lines that had been touched more recently
Can anyone tell me how to use this?
Do I need to download something? Where to put the downloaded stuff?
And if I want to have back deleted files from this folder: "Dokument"
That have this info:
Location: "/media/jonas/0e362876:data"
Filesystem: "btrfs"
Mounted on: "/media/jonas/0e362876:data"
Mounted from: "/dev/md127"
And I want to save data collected by this code here:
Name: "nas_tmp"
Location: "/media/jonas/M.2 - Recover"
Mounted on: "/media/jonas/M.2 - Recover"
Mounted from: "/dev/nvmeOn1p6"
How can I the use this "btrfs-undelete" with my info?