Üzerine yazılan dosyalar kurtarılabilir mi?


42

Silinen dosyaları değil, üzerine yazılmış dosyaları kurtarmaktan bahsetmiyorum . Yani aşağıdaki yöntemlerle:

# move
mv new_file old_file

# copy
cp new_file old_file

# edit
vi existing_file
> D
> i new_content
> :x

Linux makinesinde hiçbir özel program kurulu olmadığı varsayımıyla yukarıdaki üç işlemden herhangi biri gerçekleştirilirse, herhangi bir şey elde etmek mümkün müdür?


4
Yedeklerin dışında mı demek istiyorsun?
jasonwryan

@ jasonwryan, evet, elbette.
Soru Taşma

2
Ben sadece ilk örneğinizin ( mv) silme old_filegibi olduğunu, üzerine yazmak yerine yazdığını, bu yüzden üzerine yazılmış dosyaların aksine silinmiş dosyaları kurtarma yöntemlerinin (varsa) geçerli olacağını belirtmek isterim. Diğer iki örneğiniz de sırasıyla old_fileve mevcut olanların üzerine existing_fileyazıyor.
Celada

Sağladığınız her üç örnek, tüm orijinal dosyanın veri bloklarını silerek ve yeni ayrılan bloklara yazarak uygulanır ve bu verilerin kurtarılması prosedürü silinmiş bir dosyayı kurtarmakla aynıdır. Bunun bir istisnası, orijinal dosyalar aşırı kısasa (ext4'te 60 bayttan kısa), buradaki son iki örnek önceki verileri kurtarılamaz duruma getirir.
Mark Plotnick

1
@MarkPlotnick, Celada'nın yorumuna göre mv, farklı.
Soru Taşması,

Yanıtlar:


59

Cevap "Muhtemelen evet, ancak dosya sistemi türüne ve zamanlamasına bağlı."

Bu üç örnekten hiçbiri, old_file veya exist_file öğesinin fiziksel veri bloklarının, şans eseri haricinde üzerine yazmayacak.

  • mv new_file old_file. Bu old_file'in bağlantısını kaldırır. Old_file dosyasına ek sabit linkler varsa, kalan linklerde bloklar değişmeden kalacaktır. Aksi takdirde, bloklar genellikle (dosya sistemi türüne göre değişir) ücretsiz bir listeye yerleştirilir. Daha sonra, eğer mvkopyalama gerekiyorsa (sadece hareketli dizin girişlerinin aksine), yeni bloklar mvyazma olarak tahsis edilecektir .

    Yeni tahsis edilen bu bloklar , henüz serbest bırakılanlarla aynı olabilir veya olmayabilir . UFS gibi dosya sistemlerinde , bloklar, mümkünse, dosyanın oluşturulduğu dizinin aynı silindir grubundan ayrılır. Bu nedenle, bir dosyayı bir dizinden ayırmanın ve aynı dizinde bir dosya oluşturmanın yeniden kullanılma olasılığı vardır ( ve üzerine yaz) sadece serbest bırakılan bloklardan bazıları. Bu nedenle, bir dosyayı yanlışlıkla silen insanlara standart tavsiye, birisi dosya kurtarma girişiminde bulunana kadar, dizin ağacındaki dosyalara (ve tercihen tüm dosya sistemine) yeni veri yazmamaktır.

  • cp new_file old_fileşunları yapacak ( stracesistem çağrılarını görmek için kullanabilirsiniz):

    açık ("old_file", O_WRONLY | O_TRUNC) = 4

    O_TRUNC bayrağı, mvyukarıda olduğu gibi tüm veri bloklarının serbest kalmasına neden olacaktır . Ve yukarıda olduğu gibi, genellikle ücretsiz bir listeye eklenirler ve cpkomut tarafından yapılan sonraki yazılar tarafından yeniden kullanılabilirler veya yeniden kullanılamazlar .

  • vi existing_file. Eğer viöyleyse vim, :xkomut aşağıdakileri yapar:

    unlink ("existing_file ~") = -1 ENOENT (Böyle bir dosya veya dizin yok)
    yeniden adlandır ("existing_file", "existing_file ~") = 0
    açık ("existing_file", O_WRONLY | O_CREAT | O_TRUNC, 0664) = 3

    Yani eski verileri bile kaldırmaz; veriler bir yedekleme dosyasında korunur.

    FreeBSD üzerindeyken viyaptığı open("existing_file",O_WRONLY|O_CREAT|O_TRUNC, 0664)aynı anlamlara sahip olan, cpyukarıda.


Özel programlar olmadan verilerin bir kısmını veya tamamını kurtarabilirsiniz; tüm ihtiyaç vardır grepve ddve ham cihaza erişim.

Küçük metin dosyaları için, bağladığınız sorudaki @Steven D'grep nin cevabındaki tek komut en kolay yoldur:

grep -i -a -B100 -A100 'text in the deleted file' /dev/sda1

Ancak birden çok bitişik olmayan bloklarda olabilecek daha büyük dosyalar için şunu yapıyorum:

grep -a -b "text in the deleted file" /dev/sda1
13813610612:this is some text in the deleted file

bu size eşleşen çizginin bayt cinsinden ofsetini verecektir. Bunu bir dizi ddkomutla izleyin.

dd if=/dev/sda1 count=1 skip=$(expr 13813610612 / 512)

Ayrıca bu bloktan önce ve sonra birkaç blok okumak istersiniz. UFS'de, dosya blokları genellikle 8KB'dir ve genellikle oldukça bitişik olarak tahsis edilir, tek bir dosyanın blokları diğer dosyalardan veya boş alandan gelen 8 KB bloklarla dönüşümlü olarak birleştirilir. UFS'deki bir dosyanın kuyruğu, bitişik olabilen veya olamayabilen 7 KB değerine kadardır.

Elbette, verileri sıkıştıran veya şifreleyen dosya sistemlerinde, kurtarma işlemi bu kadar basit olmayabilir.


Unix'te mevcut bir dosyanın veri bloklarının üzerine yazacak çok az yardımcı program var. Akla gelen bir şey var dd conv=notrunc. Başka bir shred.


3
Üç farklı işlemin iç mekaniğini açıkladığınız için teşekkür ederiz. Bu gerçekten yararlı!
Soru Taşması

btrfssilinen dosyalara oldukça dayanıklıdır. Blokları yuvarlak robin biçiminde kullanma eğilimindedir, bu nedenle aygıtta yeterli alanınız varsa dosyanın üzerine uzun süre yazılmaz. Buraya
pqnet

Bir önceki metin bloğunu nasıl alırsınız ve atlama ne yapar?
05'te unixit

@Islam dd skip=parametresini verdiğinizde , girişin başından okumak yerine, bu blok sayısını atlayacaktır. Bir blok, varsayılan olarak 512 bayttır, ancak bs=parametre ile değiştirilebilir .
Mark Plotnick,

1
@Islam Yukarıdaki metin bloğunu almak için skip=1 blok (512 bayt) daha az bir değer vermenizi öneririm . Benim örneğimde $(expr 13813610612 / 512 - 1). Bu istediğinizi elde etmezse, 8192 ve 16384 bayt daha az olan alanlara bakacak şekilde 16 veya 32'yi çıkarırken tekrar deneyin; dosyalar genellikle 8192 bayt boyutunda ayrılır. Daha büyük bir dosyayı kurtarmaya çalışıyorsanız, zaman kazanmak için daha büyük sayıları deneyin. Verilerin bir kısmının metin olmaması önemli değil, genellikle count=16bir editörde sonucu kullanırım emacs.
Mark Plotnick,

6

Hayır diyeceğim (dev bir yıldızla).

Verilerin bir diske nasıl yerleştirildiğini düşünün. Veri içeren ve bir sonraki bloğa işaret eden bloklarınız var (varsa).

Verilerin üzerine yazdığınızda blok içeriğini değiştirirsiniz (ve dosyayı tüm bitiş işaretleyicisini genişletiyorsanız). Hiçbir şey Yani gerektiğini kurtarılamaz muktedir (aşağıya bakınız).

Dosyayı kısaltırsanız, eski blokları kaybediyorsunuz ve yakında geri dönüştürülecekler. Programcıysanız, ücretsiz / silmeden listenizin yarısını "kaybettiğiniz" bağlantılı bir liste düşünün. Bu veri hala orada, ama bulmada iyi şanslar.

Düşünmesi ilginç olabilecek bir şey parçalanmadır.

Parçalanma, diskinizde bitişik olmayan verilerin "delikleri" varken oluşur. Bunun nedeni, dosyaları uzatacak veya kısaltacak şekilde değiştirmenizden kaynaklanabilir ve artık diskteki orijinal noktalarına uymazlar.

Bir dosyanın orijinal boyutunun üzerine çıkması durumunda (bu noktada taşınması gerekir), dosya sisteminize bağlı olarak tüm dosyayı eski verilerin hala orada olacağı (ancak ücretsiz olarak işaretlenmiş) yeni bir konuma kopyalayabilirsiniz. ya da sadece eski bitiş işaretçisini değiştirirsiniz ve yeni bir konuma işaret etmesini sağlarsınız (bu, gevşemeye neden olur).

Uzun lafın kısası, verileriniz büyük olasılıkla kayboluyor (mikroskopta baktığınız aşırı adli bir süreçten geçmeden); Ancak, hala orada olma şansı var.


1
Cevabınız bir blok tabanlı olmayan kopya üzerinde yazma dosya sistemi gibi varsayım yapar ext4veya xfskullanımda. Yazma dosya sistemlerindeki kopya ile zfsve btrfsaslında asla "blok içeriğini değiştirmez"; bu dosya sistemleri her zaman yeni veriler içerecek şekilde yeni bloklar kullanır. Ayrıca, günlük tabanlı dosya sistemleri jffs2de her zaman yeni konumlara yeni veri yazar ("bloklar" değil, bu dosya sistemleri blok temelli değildir). Olduğu söyleniyor, bu eski verilerin nerede yaşadığını bulmak ve alan geri dönüştürülmeden önce yapmak için kolay olduğu anlamına gelmez. Yani hayır olan cevabınız hala doğru
Celada

@Celada Teşekkürler! Bunu çok bilgilendirici buldum. Btrfs veya zfs'nin nasıl çalıştığına bakmaya vaktim olmadı, ancak onların var olduğunu biliyordum.
SailorCire

2

/ Var / tmp veya büyük bir yerde yeterli disk alanınız olduğundan emin olun.

Deneyin

 grep -i -a -B100 -A100 'a string unique to your file' /dev/sda1 |
 strings > /var/tmp/my-recovered-file

nerede / dev / sda1 sisteminizde diskiniz olur.

Sonra benim kurtarılan dosyamı senin için araştır.

Bu olabilir bunu eksik linespaces, parantez, sysmbols vb kontrol bulursanız çoğunlukla, söz konusu

Dosyanızda oldukça unidue olan bir arama kelimesini veya dosyadaki veri miktarını azaltacak bir dize kullanın. Eğer "echo" gibi bir kelime ararsanız, sistemde bunlarda echo kelimesiyle birçok dosyaya sahip olacağından dizgelerin çoğunu geri alırsınız.


0

12 saat değerinde test verisine sahip bir metin dosyasının (VQ1.txt) üzerine yazmıştım :( Unix'in dosyanın önceki sürümünü text.txt ~ biçiminde kaydettiği bir fikir, üzerine $ -ll Full yazılan dosyanın bulunduğu klasörü aramamı sağladı. listesi, 'kayıp' verilerimi içeren VQ1.txt dosyasını gösterdi!

$ cat VQ1.txt~  
Start time at: Thu Apr  2 18:07:23 PDT 2015
User, KW: 12hrFA_OEM_HelloVoiceQ
Test Case: 
Detection:  1, 1, 04-03 01:07:00.673 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  2, 1, 04-03 01:09:04.813 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  3, 1, 04-03 04:09:26.023 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  4, 1, 04-03 04:11:29.893 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  5, 1, 04-03 07:12:27.013 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  6, 1, 04-03 07:14:30.803 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  7, 1, 04-03 08:37:13.113 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  8, 1, 04-03 10:21:23.533 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  9, 1, 04-03 10:23:27.733 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  10, 1, 04-03 13:23:47.893 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  11, 1, 04-03 13:25:52.203 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1

12hrFA_OEM_HelloVoiceQ,  
KW detect count: 11

4
Bu genel olarak Unix yerine bazı metin editörlerinin bir özelliği değil mi? Dosyaların eski sürümlerini bu şekilde kaydeden bir dosya sisteminin farkında değilim.
Joey

0

TL; DR - Üzerine yazılan dosya hala devam eden bir işlem tarafından açık tutuluyorsa, bu blog yazısı domuz pastırmanızı koruyabilir:

https://www.linux.com/news/bring-back-deleted-files-lsof/

İçinde silinmiş dosyalar hakkında konuşuyor , ancak rsync tarafından yazılmış bir dosyada bile şansım yaver gitti. Üstelik 4 MB'lık bir dosyanın üzerine yazılmış 60 GB'lik bir dosyadan da bahsediyorum ve orijinali geri kazanabildim çünkü neyse ki açık olan çalışan işlemi durdurmadım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.