-
-
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 |
Q1: does it recover only delete, or all files in given directory?
Q2: is there a possibility to speed the script up (quit early safely)? It recovered most of my files on (16/173)
and now I'm just sitting here..is it safe to kill the process early?
Thanks!
Thank you! It saved me! For some reason, the file began to occupy 0 bytes. This script is the only thing that helped to restore.
doesn't seem to work.
This script totally saved my movie collection folder!
You are sorting byte-addresses descending instead of generation ids descending, aren't you?
Wow! perfect. It's was a beatful work. Thanks a lot
This script is successfully creating files that appear to be the correct size, but they cannot be opened or read correctly with the relevant programs. Not sure what could be wrong here, as the script seems to be working?
This worked perfectly, better than I ever could have expected, for me. The files I was recovering had only been deleted about 2 minutes before I used the script and I was able to unmount the drive 10 seconds after I accidentally deleted (rm -r) the files.
Perfect!
I try to restore my file but i got this errors
recover.sh: 32: Bad substitution
command
sudo sh recover.sh /dev/sda /home/jamal/project/work_payments/* /home/jamal/restore/
Thank you very much for this script! Did something silly with dvc remove on a directory containing some files that were not committed yet, and your script was able to recover the files.
[root@doadgrz starterx4]# /home/starterx4/Pulpit/btrfs-undelete.sh /dev/sdb3 * /mnt/xir/~Btrfs/un/
mktemp: failed to create directory via template ‘akt2.png/btrfs-undelete.XXXXX’: Not a directory
Searching roots...
Trying root 53695479808... (1/33)
Recovered 24085 non-empty file(s) into
[root@doadgrz starterx4]#
And then the destination directory is empty. What's happening?
Ah ok, there must be "/" instead of "".
Altough, i tried to restore files manually, but my filesystem must be really messed up.
[root@doadgrz tmp]# btrfs restore -t 7303168 /dev/sdb3 /mnt/xir/~Btrfs/un/
parent transid verify failed on 7303168 wanted 99464 found 91953
parent transid verify failed on 7303168 wanted 99464 found 91953
Ignoring transid failure
WARNING: could not setup extent tree, skipping it
Couldn't setup device tree
Could not open root, trying backup super
parent transid verify failed on 7303168 wanted 99464 found 91953
parent transid verify failed on 7303168 wanted 99464 found 91953
Ignoring transid failure
WARNING: could not setup extent tree, skipping it
Couldn't setup device tree
Could not open root, trying backup super
parent transid verify failed on 7303168 wanted 99464 found 91953
parent transid verify failed on 7303168 wanted 99464 found 91953
Ignoring transid failure
WARNING: could not setup extent tree, skipping it
Couldn't setup device tree
Could not open root, trying backup super
[root@doadgrz tmp]#
find-root now needs the -a option to list more than one roots
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?
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
👍 saved my day (and ass/data) today! :) Do you plan to turn it into a small repo or package it, so it doesnt get lost?