memulihkan file yang dihapus disimpan terbuka oleh apache?

10

Misalkan file log apache dihapus tetapi tetap dibuka oleh apache; maka inilah yang saya lakukan:

pid=$(lsof | grep text.txt | awk '/deleted/ {print $2}')
fd=$(lsof | grep text.txt | awk '/deleted/ {print $4}' | grep -oE "[[:digit:]]{1,}")

cp /proc/$pid/fd/$fd directorytobecopied/testfile.txt

Inilah yang saya lakukan untuk memulihkan file dan mengembalikannya ke tempat semula. Apakah ada cara yang lebih sederhana untuk melakukan ini karena kode di atas tidak terlihat bagus. Selanjutnya bagaimana saya tahu dari mana file itu dihapus ( directorytobecopied ) sehingga saya tidak perlu bertanya secara manual kepada seseorang di mana file itu berada semula dan meletakkannya kembali di sana.

munish
sumber
lsof / | awk '(/deleted/||/abc.txt/) {print "FD :-",$4,"| File Name:-",$9}'
Rahul Patil

Jawaban:

14

Jika file telah dihapus tetapi masih terbuka, itu berarti file tersebut masih ada di sistem file (memiliki inode ) tetapi memiliki jumlah tautan keras 0. Karena tidak ada tautan ke file, Anda tidak dapat membukanya dengan nama . Tidak ada fasilitas untuk membuka file dengan inode juga.

Tidak ada cara untuk menemukan file melalui sistem file-nya, dan terutama tidak ada cara untuk mencari file di direktori tempat terakhir. Entri direktori hilang. Yang tersisa hanyalah file itu sendiri. Anda bisa mendapatkan file dengan debugger sistem file, tetapi itu membutuhkan izin root dan sulit digunakan dan rentan kesalahan.

Linux mengekspos file terbuka melalui tautan simbolik khusus di bawah /proc. Tautan ini disebut di /proc/12345/fd/42mana 12345 adalah PID dari suatu proses dan 42 adalah jumlah deskriptor file dalam proses itu. Program yang berjalan sebagai pengguna yang sama dengan proses itu dapat mengakses file (izin baca / tulis / eksekusi sama dengan yang Anda miliki saat file dihapus).

Nama di mana file dibuka masih terlihat di target tautan simbolik: jika file itu /var/log/apache/foo.log, maka target tautannya adalah /var/log/apache/foo.log (deleted). (Jika file diganti nama setelah dibuka, target symlink mungkin mencerminkan penggantian nama.)

Dengan demikian Anda dapat memulihkan konten dari file yang dihapus terbuka mengingat PID dari proses yang membuatnya terbuka dan deskriptor yang dibuka seperti ini:

recover_open_deleted_file () {
  old_name=$(readlink "$1")
  case "$old_name" in
    *' (deleted)')
      old_name=${old_name%' (deleted)'}
      if [ -e "$old_name" ]; then
        new_name=$(TMPDIR=${old_name%/*} mktemp)
        echo "$oldname has been replaced, recovering content to $new_name"
      else
        new_name="$old_name"
      fi
      cat <"$1" >"$new_name";;
    *) echo "File is not deleted, doing nothing";;
  esac
}
recover_open_deleted_file "/proc/$pid/fd/$fd"

Jika Anda hanya mengetahui ID proses tetapi bukan deskriptor, Anda dapat memulihkan semua file dengan

for x in /proc/$pid/fd/*; do
  recover_open_deleted_file "$x"
done

Jika Anda juga tidak mengetahui ID proses, Anda dapat mencari di antara semua proses:

for x in /proc/[1-9]*/fd/*; do
  case $(readlink "$x") in
    /var/log/apache/*) recover_open_deleted_file "$x";;
  esac
done

Anda juga dapat memperoleh daftar ini dengan menguraikan output lsof, tetapi tidak lebih sederhana atau lebih dapat diandalkan atau lebih portabel (ini adalah Linux-spesifik bagaimanapun).

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Anda dapat membuka / proc / x / fd / y untuk membaca atau menulis terlepas dari apakah x sudah terbuka untuk membaca atau menulis.
Stéphane Chazelas
mengapa OS unix memungkinkan penghapusan file ketika terbuka ... sementara kita tidak bisa melakukannya di windows.is ada penjelasan apa pun
munish
@munish Windows dimulai dari model multitasking kooperatif: jika suatu aplikasi bertingkah buruk, itu bisa menjatuhkan sistem. Sebagian besar masalah telah diperbaiki sekarang, tetapi Windows masih memungkinkan aplikasi untuk membajak file: selama file tersebut dibuka, tidak dapat diubah namanya atau dihapus. Unix tidak mengizinkan ini: menghapus atau mengganti nama file adalah ortogonal karena dibuka.
Gilles 'SANGAT berhenti menjadi jahat'
1
Anda baru saja menyelamatkan Muse's Origin of Symmetry untuk saya! Terima kasih seribu kali lipat!
dotancohen