Làm thế nào để khôi phục tập tin bị xóa nếu nó vẫn được mở bởi một số quá trình?


18
$ cat important_file > /dev/null &
[1] 9711
$ rm important_file 
$ killall -STOP cat

[1]+  Stopped                 cat important_file > /tmp/p
$ ls -l /proc/`pidof cat`/fd/
total 0
lrwx------ 1 vi vi 64 May 13 20:32 0 -> /dev/pts/29
l-wx------ 1 vi vi 64 May 13 20:32 1 -> /tmp/p
lrwx------ 1 vi vi 64 May 13 20:32 2 -> /dev/pts/29
lr-x------ 1 vi vi 64 May 13 20:32 3 -> /home/vi/important_file (deleted)

Làm thế nào để phục hồi điều này important_file?

Tôi đã thử một cái gì đó như

injcode -m dup2 -ofd=3 -ofilename=/tmp/recovered_file -oflags=O_CREAT $PID_OF_CAT

nhưng nó không làm gì cả

Câu trả lời:


11

Nếu / home là NFS, sẽ có tệp .nfsNNNNNNNNNN trong / home / vi mà bạn có thể truy cập / sao chép. Nếu nhà là một hệ thống tệp cục bộ, bạn sẽ có thể thực hiện điều tương tự thông qua liên kết / Proc / PID / fd / 3:

cp /proc/PID/fd/3 /tmp/recovered_file

Nếu bạn thực sự muốn phục hồi tập tin, đây là một bài đăng blog về chủ đề này.


1
OK, tôi đã nhầm lẫn bởi điều đó readlink /proc/13381/fd/3-> "/ home / vi / Quan trọng_file (đã xóa)" và /home/vi/important_file\ \(deleted\)rõ ràng là không tồn tại.
Vi.

18

... tốt hơn là sao chép tại một thời điểm nhất định (và chỉ thu thập ảnh chụp nhanh nội dung của tệp đó) là " tail -f" tệp đó vào một tệp mới:

tail -c +0 -f /proc/PIDofProgram>/fd/# > /new/path/to/file

(nhờ các lập trình viên thận trọng của đuôi, thậm chí sẽ làm việc với đầu ra nhị phân.)

Trong thời gian chạy, tail -fchính nó giữ cho tệp mở, ngăn chặn nó khỏi bị xóa khỏi đĩa khi chương trình gốc kết thúc. Do đó, đừng dừng tail -fngay lập tức sau khi chương trình ban đầu của bạn kết thúc - /new/path/to/filetrước tiên hãy kiểm tra xem đuôi có phải thứ bạn muốn không. Nếu nó không (hoặc không thỏa mãn vì bất kỳ lý do nào khác), bạn có thể sao chép lại tệp gốc, nhưng lần này sau khi tất cả việc ghi vào nó đã hoàn thành bởi "Chương trình" và từ tail -fs / Proc / PIDoftail vẫn đang chạy thư mục fd /.


3
Điều gì về việc tạo một liên kết cứng đến / Proc / PIDofProgram> / fd / #?
vẫy tay

2
@becko Invalid cross-device link.
Kamil Maciorowski

9

Sử dụng lsof để tìm số inode và gỡ lỗi để tạo lại một liên kết cứng đến nó. Ví dụ:

# lsof -p 12345 | grep /var/log/messages
syslogd 12345 root    3w   REG                8,3    3000    987654 /var/log/messages (deleted)
# mount | grep var
/dev/sda2 on /var type ext3 (rw)
# debugfs -w /dev/sda2
debugfs: cd log
debugfs: ln <987654> tmp
debugfs: mi tmp
                      Mode    [0100600] 
                   User ID    [0] 
                  Group ID    [0] 
                      Size    [3181271] 
             Creation time    [1375916400] 
         Modification time    [1375916322] 
               Access time    [1375939901]
             Deletion time    [9601027] 0
                Link count    [0] 1
               Block count    [6232] 
                File flags    [0x0] 
...snip...
debugfs:  q
# mv /var/log/tmp /var/log/messages
# ls -al /var/log/messages
-rw------- 0 root root 3301 Aug  8 10:10 /var/log/messages

Trước khi bạn phàn nàn, tôi đã làm giả bảng điểm ở trên vì tôi không có tệp bị xóa ngay bây giờ ;-)

Tôi sử dụng miđể đặt lại thời gian xóa và số lượng liên kết thành các giá trị hợp lý (tương ứng 0 và 1), nhưng nó không hoạt động chính xác - bạn có thể thấy số lượng liên kết vẫn ở mức 0 in ls. Tôi nghĩ rằng kernel có thể lưu trữ dữ liệu inode. Bạn có lẽ nên fsck trong cơ hội sớm nhất sau khi sử dụng debugfs, để ở bên an toàn.

Theo kinh nghiệm của tôi, bạn nên tạo liên kết bằng tên tệp tạm thời và sau đó đổi tên thành tên thích hợp. Liên kết nó trực tiếp đến tên tệp gốc dường như gây ra hỏng thư mục. YMMV!


Tại sao chính xác là bạn đề xuất điều này nếu nó không thực sự hoạt động đúng và gây ra thiệt hại hệ thống? Tôi nghĩ bạn nên có một tuyên bố từ chối sinh động hơn trong câu trả lời rằng đây đơn giản chỉ là WiP và không nên thử trong sản xuất.
cnst

3

Bạn chỉ có thể cpcác tập tin, tức là:

cp /proc/<pid>/fd/<fdno> /new/path/to/file

Tất nhiên, nếu tệp vẫn đang được sửa đổi, bạn sẽ gặp rắc rối với phương pháp này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.