Odpowiedź brzmi: „Prawdopodobnie tak, ale zależy to od typu systemu plików i czasu”.
Żaden z tych trzech przykładów nie zastąpi fizycznych bloków danych starego_pliku lub istniejącego_pliku, z wyjątkiem przypadku.
mv new_file old_file
. To rozłączy stary plik. Jeśli istnieją dodatkowe twarde linki do old_file, bloki pozostaną niezmienione w pozostałych linkach. W przeciwnym razie bloki będą na ogół (w zależności od typu systemu plików) umieszczone na wolnej liście. Następnie, jeśli mv
wymaga kopiowania (w przeciwieństwie do tylko przenoszenia pozycji katalogu), nowe bloki zostaną przydzielone jako mv
zapisy.
Te nowo przydzielone bloki mogą, ale nie muszą być tymi samymi, które zostały właśnie uwolnione . W systemach plików, takich jak UFS , bloki są przydzielane, jeśli to możliwe, z tej samej grupy cylindrów, co katalog, w którym plik został utworzony. Istnieje więc szansa, że połączenie pliku z katalogu i utworzenie pliku w tym samym katalogu zostanie ponownie wykorzystane ( i nadpisują) niektóre z tych samych bloków, które właśnie zostały uwolnione. Dlatego standardową poradą dla osób, które przypadkowo usuną plik, jest nie zapisywanie żadnych nowych danych w plikach w drzewie katalogów (a najlepiej nie w całym systemie plików), dopóki ktoś nie spróbuje odzyskać pliku.
cp new_file old_file
wykona następujące czynności (możesz użyć, strace
aby zobaczyć wywołania systemowe):
open („stary_plik”, O_WRONLY | O_TRUNC) = 4
Flaga O_TRUNC spowoduje zwolnienie wszystkich bloków danych, podobnie jak mv
powyżej. I jak wyżej, będą one generalnie dodawane do darmowej listy i mogą, ale nie muszą, zostać ponownie wykorzystane przez kolejne zapisy wykonane przez cp
polecenie.
vi existing_file
. Jeśli vi
tak vim
, to :x
polecenie wykonuje następujące czynności:
unlink ("exist_file ~") = -1 ENOENT (Brak takiego pliku lub katalogu)
rename („istniejący_plik”, „istniejący_plik ~”) = 0
open („plik_istniejący”, O_WRONLY | O_CREAT | O_TRUNC, 0664) = 3
Więc nawet nie usuwa starych danych; dane są przechowywane w pliku kopii zapasowej.
Na FreeBSD, vi
robi open("existing_file",O_WRONLY|O_CREAT|O_TRUNC, 0664)
, który będzie miał taką samą semantykę jak cp
powyżej.
Możesz odzyskać część lub całość danych bez specjalnych programów; Wszystko czego potrzebujesz to grep
i dd
, a dostęp do urządzenia surowego.
W przypadku małych plików tekstowych jedno grep
polecenie w odpowiedzi z @Steven D w pytaniu, do którego się łączysz, jest najprostszym sposobem:
grep -i -a -B100 -A100 'text in the deleted file' /dev/sda1
Ale w przypadku większych plików, które mogą znajdować się w wielu nieciągłych blokach, robię to:
grep -a -b "text in the deleted file" /dev/sda1
13813610612:this is some text in the deleted file
co da ci przesunięcie w bajtach pasującej linii. Postępuj zgodnie z serią dd
poleceń, zaczynając od
dd if=/dev/sda1 count=1 skip=$(expr 13813610612 / 512)
Chciałbyś również przeczytać kilka bloków przed i po tym bloku. W systemie plików UFS bloki plików mają zwykle rozmiar 8 KB i zwykle są przydzielane dość ściśle, bloki jednego pliku są przeplatane naprzemiennie z blokami 8 KB z innych plików lub wolnej przestrzeni. Ogon pliku na UFS ma do 7 fragmentów 1 KB, które mogą, ale nie muszą być ciągłe.
Oczywiście w systemach plików kompresujących lub szyfrujących dane odzyskiwanie może nie być takie proste.
W Uniksie jest tak naprawdę niewiele narzędzi, które zastąpią bloki danych istniejącego pliku. Przychodzi mi na myśl jedna dd conv=notrunc
. Innym jest shred
.