You are not logged in.
I have deleted the entire directory using rm -R, totally forgetting that in it there was a .po translate file I've been working on for days.
I tried with photorec, searching for .txt files but to no avail. I recovered ~800k of txt files but searching through it didn't provide any results.
Is it recoverable at all, if so, what to use? It's on my main, linux filesystem, using ext4.
Last edited by maboleth (2020-08-29 07:46:32)
Offline
if it's SSD, disable fstrim first things first, or it'll be gone. if you mount with discard mount flag, it's already gone.
systemctl stop fstrim.timer
systemctl stop fstrim.service
chmod -x /usr/bin/fstrim
If it's a plain text file you can search it like this:
strings -w /dev/disk | grep -C 1000 -F 'unique string' | tee /dev/shm/output.txt
unique string is anything you remember that was in the text file guaranteed. for code you'd use a distinct function name.
if the file had more than 1000 lines, use a larger number for -C
PS:
strings might not work for UTF-8 ... so if your file has äöüß or similar non-ascii characters, it won't work quite this way
in that case you can use 'strings -t d /dev/disk | grep UNIQUE_ASCII' for any ascii in your file and get the data offset
Last edited by frostschutz (2020-08-29 08:04:49)
Offline
https://wiki.archlinux.org/index.php/File_recovery
Extundelete or ext4magic might help. I think a key point to do first is to make an image of the partition.
Offline
Oh i didn't know that strings trick, pretty cool!
Offline
if it's SSD, disable fstrim first things first, or it'll be gone. if you mount with discard mount flag, it's already gone.
systemctl stop fstrim.timer systemctl stop fstrim.service chmod -x /usr/bin/fstrim
If it's a plain text file you can search it like this:
strings -w /dev/disk | grep -C 1000 -F 'unique string' | tee /dev/shm/output.txt
unique string is anything you remember that was in the text file guaranteed. for code you'd use a distinct function name.
if the file had more than 1000 lines, use a larger number for -C
PS:
strings might not work for UTF-8 ... so if your file has äöüß or similar non-ascii characters, it won't work quite this way
in that case you can use 'strings -t d /dev/disk | grep UNIQUE_ASCII' for any ascii in your file and get the data offset
@frostschutz
Strings trick sounds so good.
So, yes the file uses UTF-8 Cyrillic characters (also English ones too).
So my question is - can i use your first suggestion if I search for English phrase? Or it doesn't matter because the whole file is UTF-8?
Also if I got the 2nd command right it's
strings -t d /dev/disk | grep PHRASE_IN_CYRILLIC
Is it right?
Offline
no, you'd have to search for an ascii/english string in the 2nd example, then feed the offset to dd to get the whole thing.
strings won't work for umlauts or cyrillic I'm afraid. Not sure if there is an alternative to strings that would spit out valid UTF-8... strings has encoding option but it's weird
could use grep directly but it tends to run into out-of-memory conditions (trying to read gigabytes of zeroes as a single "line")
good luck
Offline
uconv might work as a strings replacement for utf-8 text
# losetup --find --show --read-only --offset=1M /dev/SSD/home
/dev/loop0
# pv < /dev/loop0 | uconv -i -c -f utf8 -t utf8 | grep -a -C 1000 -F 'A組とB組' | tee /dev/shm/output.txt
Offline
uconv might work as a strings replacement for utf-8 text
# losetup --find --show --read-only --offset=1M /dev/SSD/home /dev/loop0 # pv < /dev/loop0 | uconv -i -c -f utf8 -t utf8 | grep -a -C 1000 -F 'A組とB組' | tee /dev/shm/output.txt
I typed this:
losetup --find --show --read-only --offset=1M /dev/nvme0n1p3/home /dev/loop0 pv < /dev/loop0 | uconv -i -c -f utf8 -t utf8 | grep -a -C 1000 -F 'даркрум' | tee /dev/shm/output.txt
And I get losetup: unexpected arguments
Please correct me if I typed/pasted something wrong, as I'm totally unfamiliar with this. Thanks!
Last edited by maboleth (2020-08-29 12:49:56)
Offline
If you are going the grep route, you could just loop through the device using `dd` to extract byte ranges from the device in a loop, then feeding that to grep. When one matches, you can print out that offset, then use dd again to retrieve content around that offset. Some pseudocode:
# NOT REAL CODE
for offset in $(seq 0 $DiskSizeInKB); do
dd if=/dev/disk-device of=/dev/stdout skip=$((offset * 1024) count=1024 | grep -aq 'unique string' && echo $offset
done
# any offsets that are printed are candidates from which to grab surrounding content with dd
# 2048 and 4096 are just arbitrary sizes, adjust to be confident to include the size of the original file
dd if/dev/disk-device of=/dev/shm/out skip=$((ListedOffset * 1024 - 2048)) count=4096
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Getting more complicated :-)
It should be as simple as 'grep -a -b -o -F 'UNIQUESTRING' /dev/disk'
as a simple alternative to photorec where it's unclear which files it finds and can't specify a string to search for.
Originally grep prints the offset and everything, so no need for anything else. I only started using 'strings | grep' since 'grep' by itself tends to run out of memory when running it on large block devices. It tries to fit an entire line into memory, but binary data might not have a newline character for a few gigabytes...
(((maybe one of the grep options makes grep handle binary data efficiently without suppressing the output of the search string byte offset ... last time I tried, I just couldn't get it to work)))
If you slice it yourself with dd, you have to use overlap as well, otherwise one block might end with UNIQUE and the next block might start with STRING and the grep UNIQUESTRING comes empty since it's divided between blocks.
So you could do that (also with losetup offset sizelimit instead of dd) and grep like 1G at a time (if you have more than 1G of RAM)
@maboleth: I don't understand why you wrote it all in one line? It's one command per line, # being the root shell prompt in this case.
Last edited by frostschutz (2020-08-29 14:43:37)
Offline
I will try this tomorrow.
I wrote it in one line because when I write
losetup --find --show --read-only --offset=1M /dev/nvme0n1p3/home
I get losetup: cannot find an unused loop device error.
Adding /dev/loop0 to the line I get error losetup: unexpected arguments
Last edited by maboleth (2020-08-30 00:10:13)
Offline