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/42
mana 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).
lsof / | awk '(/deleted/||/abc.txt/) {print "FD :-",$4,"| File Name:-",$9}'