Bisakah file yang ditimpa dipulihkan?

42

Saya tidak berbicara tentang memulihkan file yang dihapus , tetapi menimpa file. Yaitu dengan metode berikut:

# move
mv new_file old_file

# copy
cp new_file old_file

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

Apakah mungkin untuk mengambil sesuatu jika salah satu dari tiga tindakan di atas dilakukan dengan asumsi tidak ada program khusus yang diinstal pada mesin linux?

Pertanyaan Melimpah
sumber
4
Maksud Anda terlepas dari cadangan Anda?
jasonwryan
@jasonwryan, ya, tentu saja.
Pertanyaan Overflow
2
Saya hanya ingin menunjukkan bahwa contoh pertama Anda ( mv) mirip dengan menghapus old_file, bukan menimpanya, jadi metode (jika ada) untuk memulihkan file yang dihapus, sebagai lawan dari file yang ditimpa, akan berlaku dalam kasus itu. Dua contoh Anda yang lain memang menimpa yang sudah ada old_filedan existing_file, masing-masing.
Celada
Ketiga contoh yang Anda berikan diimplementasikan dengan menghapus semua blok data file asli dan menulis ke blok yang baru dialokasikan, dan prosedur untuk memulihkan data itu sama dengan memulihkan file yang dihapus. Pengecualian mungkin terjadi jika file asli sangat pendek (lebih pendek dari 60 byte pada ext4) di mana dua contoh terakhir kemungkinan membuat data sebelumnya tidak dapat dipulihkan.
Mark Plotnick
1
@MarkPlotnick, menurut komentar Celada, mvberbeda.
Pertanyaan Overflow

Jawaban:

60

Jawabannya adalah "Mungkin ya, tetapi itu tergantung pada tipe sistem file, dan waktunya."

Tidak satu pun dari ketiga contoh akan menimpa blok data fisik old_file atau existing_file, kecuali secara kebetulan.

  • mv new_file old_file. Ini akan membatalkan tautan old_file. Jika ada tautan keras tambahan ke old_file, blok akan tetap tidak berubah di tautan yang tersisa. Jika tidak, blok umumnya (tergantung pada jenis sistem file) ditempatkan pada daftar gratis. Kemudian, jika mvmembutuhkan penyalinan (yang bertentangan dengan hanya memindahkan entri direktori), blok baru akan dialokasikan sebagai tulisan mv.

    Blok-blok yang baru dialokasikan ini mungkin atau mungkin tidak sama dengan yang baru saja dibebaskan . Pada sistem file seperti UFS , blok dialokasikan, jika mungkin, dari grup silinder yang sama dengan direktori tempat file tersebut dibuat. Jadi ada peluang untuk memutuskan tautan file dari direktori dan membuat file di direktori yang sama akan digunakan kembali ( dan menimpa) beberapa blok yang sama yang baru saja dibebaskan. Inilah sebabnya mengapa saran standar untuk orang-orang yang secara tidak sengaja menghapus file adalah untuk tidak menulis data baru ke file di pohon direktori mereka (dan lebih disukai tidak ke seluruh sistem file) sampai seseorang dapat mencoba pemulihan file.

  • cp new_file old_fileakan melakukan hal berikut (Anda dapat menggunakan straceuntuk melihat panggilan sistem):

    open ("old_file", O_WRONLY | O_TRUNC) = 4

    Bendera O_TRUNC akan menyebabkan semua blok data dibebaskan, seperti yang mvdilakukan di atas. Dan seperti di atas, mereka umumnya akan ditambahkan ke daftar gratis, dan mungkin atau tidak dapat digunakan kembali oleh penulisan selanjutnya yang dilakukan oleh cpperintah.

  • vi existing_file. Jika vibenar vim, :xperintah melakukan hal berikut:

    batalkan tautan ("existing_file ~") = -1 ENOENT (Tidak ada file atau direktori seperti itu)
    rename ("existing_file", "existing_file ~") = 0
    open ("existing_file", O_WRONLY | O_CREAT | O_TRUNC, 0664) = 3

    Jadi bahkan tidak menghapus data lama; data disimpan dalam file cadangan.

    Pada FreeBSD, viapakah open("existing_file",O_WRONLY|O_CREAT|O_TRUNC, 0664), yang akan memiliki semantik yang sama dengan cp, di atas.


Anda dapat memulihkan sebagian atau semua data tanpa program khusus; yang Anda butuhkan adalah grepdan dd, dan akses ke perangkat mentah.

Untuk file teks kecil, grepperintah tunggal dalam jawaban dari @Steven D dalam pertanyaan yang Anda tautkan adalah cara termudah:

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

Tetapi untuk file yang lebih besar yang mungkin berada di beberapa blok yang tidak bersebelahan, saya melakukan ini:

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

yang akan memberi Anda offset dalam byte dari garis yang cocok. Ikuti ini dengan serangkaian ddperintah, dimulai dengan

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

Anda juga ingin membaca beberapa blok sebelum dan sesudah blok itu. Pada UFS, blok file biasanya 8KB dan biasanya dialokasikan cukup berdekatan, satu blok file disisipkan secara bergantian dengan blok 8KB dari file lain atau ruang kosong. Ekor file di UFS hingga 7 1KB fragmen, yang mungkin atau mungkin tidak berdekatan.

Tentu saja, pada sistem file yang memampatkan atau mengenkripsi data, pemulihan mungkin tidak semudah ini.


Sebenarnya ada sangat sedikit utilitas di Unix yang akan menimpa blok data file yang ada. Salah satu yang terlintas dalam pikiran adalah dd conv=notrunc. Yang lain adalah shred.

Tandai Plotnick
sumber
3
Terima kasih telah menjelaskan mekanisme bagian dalam dari tiga operasi yang berbeda. Ini sangat berguna!
Pertanyaan Overflow
btrfscukup tangguh untuk file yang dihapus. Itu cenderung menggunakan blok dalam mode round-robin, jadi jika Anda memiliki cukup ruang pada perangkat file tidak akan ditimpa untuk waktu yang lama. Lihat di sini
pqnet
bagaimana cara mendapatkan blok teks sebelumnya dan apa yang dilewati lakukan?
unixit
@Islam Ketika Anda memberikan skip=parameter dd , maka alih-alih membaca dari awal input, ia akan melewati jumlah blok itu. Blok adalah 512 byte secara default, tetapi dapat diubah dengan bs=parameter.
Mark Plotnick
1
@Islam Untuk mendapatkan blok teks sebelumnya, saya sarankan memberikan skip=nilai yang 1 blok (512 byte) kurang. Dalam contoh saya $(expr 13813610612 / 512 - 1),. Jika itu tidak mendapatkan apa yang Anda inginkan, coba lagi sambil mengurangi 16 atau 32, yang akan melihat area yang lebih sedikit 8192 dan 16384 byte; file sering dialokasikan dalam potongan 8192-byte. Jika Anda mencoba memulihkan file yang lebih besar, cobalah jumlah yang lebih besar untuk menghemat waktu. Saya biasanya menggunakan count=16dan melihat hasilnya di editor seperti emacsyang tidak masalah jika beberapa data bukan teks.
Mark Plotnick
6

Saya akan mengatakan tidak (dengan tanda bintang raksasa).

Pikirkan tentang bagaimana data diletakkan pada disk. Anda memiliki blok yang berisi data dan arahkan ke blok berikutnya (jika ada).

Ketika Anda menimpa data, Anda mengubah konten blok (dan jika Anda memperluas file semua penanda akhir). Jadi tidak ada harus dapat dipulihkan (lihat di bawah).

Jika Anda memperpendek file, maka Anda kehilangan blok lama dan mereka akan segera didaur ulang. Jika Anda seorang programmer, pikirkan daftar tertaut di mana Anda "kehilangan" setengah dari daftar Anda tanpa melakukan free / delete. Data itu masih ada, tapi semoga berhasil menemukannya.

Sesuatu yang mungkin menarik untuk dipikirkan adalah fragmentasi.

Fragmentasi terjadi ketika Anda memiliki "lubang" data yang tidak bersebelahan pada disk Anda. Hal ini dapat disebabkan oleh memodifikasi file sedemikian rupa sehingga Anda memperpanjang atau mempersingkat mereka dan mereka tidak lagi sesuai dengan tempat aslinya pada disk.

Jika file tumbuh melebihi ukuran aslinya (perlu dipindahkan pada saat ini), tergantung pada sistem file Anda, Anda dapat menyalin seluruh file ke lokasi baru di mana data lama masih ada di sana (tetapi ditandai sebagai gratis) atau Anda hanya mengubah pointer akhir yang lama dan mengarahkannya ke lokasi baru (ini akan menyebabkan meronta-ronta).

Singkatnya, data Anda mungkin hilang (tanpa melalui proses forensik ekstrem di mana Anda melihatnya di bawah mikroskop); Namun, ada kemungkinan masih ada.

SailorCire
sumber
1
Jawaban Anda membuat asumsi bahwa sistem file non-copy-on-tulis berbasis blok seperti ext4atau xfssedang digunakan. Dengan menyalin pada sistem file tulis seperti zfsdan btrfsAnda sebenarnya tidak pernah "mengubah isi blok"; filesystem tersebut selalu menggunakan blok baru untuk memuat data baru. Selain itu, sistem file berbasis log seperti jffs2juga selalu menulis data baru ke lokasi baru (bukan "blok", sistem file tersebut tidak berbasis blok). Yang sedang berkata, ini tidak berarti mudah untuk menemukan di mana data lama tinggal dan melakukannya sebelum ruang didaur ulang. Jadi jawaban Anda, yang tidak, masih benar
Celada
@Celada Terima kasih! Saya menemukan itu sangat informatif. Saya belum punya waktu untuk melihat bagaimana btrfs atau zfs bekerja, tetapi saya tahu mereka ada.
SailorCire
2

Pastikan Anda memiliki ruang disk yang cukup di / var / tmp atau di tempat yang besar.

Mencoba

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

di mana / dev / sda1 akan menjadi disk Anda di sistem Anda.

Kemudian cari file saya-pulih untuk string Anda.

Ini mungkin sebagian besar berada di sana, Jika Anda merasa memeriksa hilang linespaces, kurung, sysmbols dll

Gunakan kata pencarian dari file Anda yang cukup unqiue atau string yang akan mengurangi jumlah data dalam file. Jika Anda mencari kata seperti "gema" Anda akan mendapatkan kembali banyak string karena sistem akan memiliki banyak file dengan kata gema di dalamnya.

AndyM
sumber
0

Saya telah menimpa file teks (VQ1.txt) dengan data pengujian senilai 12 jam :( Gagasan bahwa unix menyimpan versi file sebelumnya dalam format text.txt ~, membuat saya melihat ke folder yang berisi file yang ditimpa dengan $ -l Full daftar menunjukkan VQ1.txt ~ yang memiliki data 'hilang' saya!

$ 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
catsat
sumber
4
Bukankah itu lebih merupakan fitur editor teks tertentu daripada Unix secara umum? Saya tidak mengetahui sistem file yang menyimpan versi file lama seperti itu.
Joey
0

TL; DR - Jika file yang ditimpa masih ditahan terbuka oleh proses yang sedang berjalan, maka posting blog ini mungkin menghemat daging Anda:

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

Di dalamnya, ia berbicara tentang file yang dihapus , tetapi saya beruntung dengan itu bahkan dengan file yang ditimpa oleh rsync. Dan saya berbicara tentang file 60 GB yang ditimpa oleh file 4 MB, dan saya dapat memulihkan yang asli karena untungnya saya tidak menghentikan proses yang sedang berjalan agar tetap terbuka.

fulv
sumber