Câu trả lời là "Có thể là có, nhưng nó phụ thuộc vào loại hệ thống tập tin và thời gian."
Không ai trong số ba ví dụ này sẽ ghi đè lên các khối dữ liệu vật lý của old_file hoặc current_file, ngoại trừ tình cờ.
mv new_file old_file
. Điều này sẽ hủy liên kết old_file. Nếu có thêm các liên kết cứng đến old_file, các khối sẽ không thay đổi trong các liên kết còn lại. Mặt khác, các khối nói chung sẽ (tùy thuộc vào loại hệ thống tệp) được đặt trong danh sách miễn phí. Sau đó, nếu mv
yêu cầu sao chép (trái ngược với chỉ di chuyển các mục trong thư mục), các khối mới sẽ được phân bổ dưới dạng mv
ghi.
Các khối mới được phân bổ này có thể hoặc không thể là cùng một khối đã được giải phóng . Trên các hệ thống tệp như UFS , các khối được phân bổ, nếu có thể, từ cùng một nhóm hình trụ với thư mục mà tệp được tạo. Vì vậy, có khả năng hủy liên kết tệp từ một thư mục và tạo tệp trong cùng thư mục đó sẽ sử dụng lại ( và ghi đè lên) một số khối tương tự đã được giải phóng. Đây là lý do tại sao lời khuyên tiêu chuẩn cho những người vô tình xóa tệp là không ghi bất kỳ dữ liệu mới nào vào các tệp trong cây thư mục của họ (và tốt nhất là không cho toàn bộ hệ thống tệp) cho đến khi ai đó có thể thử phục hồi tệp.
cp new_file old_file
sẽ làm như sau (bạn có thể sử dụng strace
để xem các cuộc gọi hệ thống):
mở ("old_file", O_WRONLY | O_TRUNC) = 4
Cờ O_TRUNC sẽ khiến tất cả các khối dữ liệu được giải phóng, giống như mv
đã làm ở trên. Và như trên, chúng thường sẽ được thêm vào một danh sách miễn phí, và có thể hoặc không được sử dụng lại bởi các lần ghi tiếp theo được thực hiện bởi cp
lệnh.
vi existing_file
. Nếu vi
thực sự vim
, :x
lệnh thực hiện như sau:
hủy liên kết ("current_file ~") = -1 ENOENT (Không có tệp hoặc thư mục như vậy)
đổi tên ("current_file", "current_file ~") = 0
mở ("current_file", O_WRONLY | O_CREAT | O_TRUNC, 0664) = 3
Vì vậy, nó thậm chí không loại bỏ dữ liệu cũ; dữ liệu được lưu giữ trong một tập tin sao lưu.
Trên FreeBSD, vi
không open("existing_file",O_WRONLY|O_CREAT|O_TRUNC, 0664)
, mà sẽ có ngữ nghĩa tương tự như cp
ở trên.
Bạn có thể khôi phục một số hoặc tất cả dữ liệu mà không cần các chương trình đặc biệt; tất cả những gì bạn cần là grep
và dd
, và truy cập vào thiết bị thô.
Đối với các tệp văn bản nhỏ, grep
lệnh đơn trong câu trả lời từ @Steven D trong câu hỏi bạn liên kết đến là cách dễ nhất:
grep -i -a -B100 -A100 'text in the deleted file' /dev/sda1
Nhưng đối với các tệp lớn hơn có thể nằm trong nhiều khối không liền kề, tôi thực hiện việc này:
grep -a -b "text in the deleted file" /dev/sda1
13813610612:this is some text in the deleted file
sẽ cung cấp cho bạn phần bù theo byte của dòng khớp. Thực hiện theo điều này với một loạt các dd
lệnh, bắt đầu bằng
dd if=/dev/sda1 count=1 skip=$(expr 13813610612 / 512)
Bạn cũng muốn đọc một số khối trước và sau khối đó. Trên UFS, các khối tệp thường là 8KB và thường được phân bổ khá liền kề, các khối của một tệp được xen kẽ xen kẽ với các khối 8KB từ các tệp khác hoặc không gian trống. Đuôi của một tệp trên UFS có tới 7 đoạn 1KB, có thể hoặc không thể tiếp giáp nhau.
Tất nhiên, trên các hệ thống tệp nén hoặc mã hóa dữ liệu, việc khôi phục có thể không đơn giản như vậy.
Thực tế có rất ít tiện ích trong Unix sẽ ghi đè lên các khối dữ liệu của tệp hiện có. Một trong đó đến với tâm trí là dd conv=notrunc
. Khác là shred
.