Tập tin ghi đè có thể được phục hồi?


42

Tôi không nói về việc khôi phục các tập tin bị xóa , nhưng ghi đè lên các tập tin. Cụ thể bằng các phương pháp sau:

# move
mv new_file old_file

# copy
cp new_file old_file

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

Có thể truy xuất bất cứ điều gì nếu bất kỳ hành động nào trong ba hành động trên được thực hiện với giả định không có chương trình đặc biệt nào được cài đặt trên máy linux không?


4
Bạn có nghĩa là ngoài bản sao lưu của bạn?
jasonwryan

@jasonwryan, vâng, tất nhiên rồi.
Câu hỏi tràn vào

2
Tôi chỉ muốn chỉ ra rằng ví dụ đầu tiên của bạn ( mv) gần giống với việc xóa old_file, không ghi đè lên nó, vì vậy các phương thức (nếu có) để khôi phục các tệp đã bị xóa, trái với các tệp bị ghi đè, sẽ được áp dụng trong trường hợp đó. Hai ví dụ khác của bạn thực sự ghi đè lên một hiện có old_fileexisting_file, tương ứng.
Celada

Tất cả ba ví dụ bạn cung cấp được thực hiện bằng cách xóa tất cả các khối dữ liệu của tệp gốc và ghi vào các khối được phân bổ mới và quy trình khôi phục dữ liệu đó giống như khôi phục tệp đã bị xóa. Một ngoại lệ có thể là nếu các tệp gốc quá ngắn (ngắn hơn 60 byte trên ext4) trong đó hai ví dụ sau có thể làm cho dữ liệu trước đó không thể phục hồi được.
Đánh dấu Plotnick

1
@MarkPlotnick, theo nhận xét của Celada, mvthì khác.
Câu hỏi tràn

Câu trả lời:


60

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 mvyê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 mvghi.

    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_filesẽ 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 cplệnh.

  • vi existing_file. Nếu vithực sự vim, :xlệ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, vikhô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à grepdd, và truy cập vào thiết bị thô.

Đối với các tệp văn bản nhỏ, greplệ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 ddlệ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.


3
Cảm ơn bạn đã giải thích các cơ chế bên trong của ba hoạt động khác nhau. Điều này thực sự hữu ích!
Câu hỏi tràn

btrfslà khá đàn hồi để xóa các tập tin. Nó có xu hướng sử dụng các khối theo kiểu vòng tròn, vì vậy nếu bạn có đủ dung lượng trên thiết bị, tệp sẽ không bị ghi đè trong một thời gian dài. Xem tại đây
pqnet

làm thế nào để có được khối văn bản có sẵn và bỏ qua làm gì?
unixit

@Islam Khi bạn cung cấp cho dd skip=tham số, sau đó thay vì đọc từ đầu vào, nó sẽ bỏ qua số khối đó. Một khối là 512 byte theo mặc định, nhưng có thể được thay đổi với bs=tham số.
Đánh dấu Plotnick

1
@Islam Để có được khối văn bản trước, tôi khuyên bạn nên cung cấp một skip=giá trị ít hơn 1 khối (512 byte). Trong ví dụ của tôi , $(expr 13813610612 / 512 - 1). Nếu điều đó không đạt được những gì bạn muốn, hãy thử lại trong khi trừ 16 hoặc 32, sẽ xem xét các khu vực ít hơn 8192 và 16384 byte; các tệp thường được phân bổ trong các khối 8192 byte. Nếu bạn đang cố khôi phục một tệp lớn hơn, hãy thử số lượng lớn hơn để tiết kiệm thời gian. Tôi thường sử dụng count=16và xem kết quả trong một trình soạn thảo emacsmà không bận tâm nếu một số dữ liệu không phải là văn bản.
Đánh dấu Plotnick

6

Tôi sẽ nói không (với một dấu sao khổng lồ).

Hãy suy nghĩ về cách dữ liệu được đặt trên một đĩa. Bạn có các khối chứa dữ liệu và trỏ đến khối tiếp theo (nếu có).

Khi bạn ghi đè dữ liệu, bạn sẽ thay đổi nội dung khối (và nếu bạn đang mở rộng tệp tất cả các điểm đánh dấu kết thúc). Vì vậy, không có gì nên có thể được phục hồi (xem dưới đây).

Nếu bạn rút ngắn tập tin, thì bạn sẽ mất các khối cũ và chúng sẽ sớm được tái chế. Nếu bạn là lập trình viên, hãy nghĩ đến một danh sách được liên kết nơi bạn "mất" một nửa danh sách mà không thực hiện miễn phí / xóa. Dữ liệu đó vẫn còn đó, nhưng chúc may mắn tìm thấy nó.

Một cái gì đó có thể thú vị để suy nghĩ là phân mảnh.

Sự phân mảnh xảy ra khi bạn có "lỗ hổng" dữ liệu không liền kề trên đĩa của mình. Điều này có thể được gây ra bằng cách sửa đổi các tệp sao cho bạn mở rộng hoặc rút ngắn chúng và chúng không còn vừa với vị trí ban đầu của chúng trên đĩa.

Trong trường hợp có một tệp phát triển vượt quá kích thước ban đầu của nó (nó cần phải di chuyển vào thời điểm này), tùy thuộc vào hệ thống tệp của bạn, bạn có thể sao chép toàn bộ tệp vào một vị trí mới nơi dữ liệu cũ vẫn còn ở đó (nhưng được đánh dấu là miễn phí) hoặc bạn chỉ cần thay đổi con trỏ kết thúc cũ và để nó trỏ đến một vị trí mới (điều này sẽ dẫn đến việc đập).

Câu chuyện dài ngắn, dữ liệu của bạn có thể bị mất (mà không trải qua một quá trình pháp y cực đoan nơi bạn nhìn vào nó dưới kính hiển vi); tuy nhiên, có một cơ hội là nó vẫn còn đó.


1
Câu trả lời của bạn làm cho các giả định rằng một hệ thống tập tin không copy-on-write khối dựa trên ví dụ như ext4hay xfsđược sử dụng. Với bản sao trên các hệ thống tập tin ghi như zfsbtrfstrên thực tế bạn không bao giờ "thay đổi nội dung khối"; những hệ thống tập tin đó luôn sử dụng các khối hoàn toàn mới để chứa dữ liệu mới. Ngoài ra, các hệ thống tệp dựa trên nhật ký jffs2cũng như luôn ghi dữ liệu mới vào các vị trí mới (không phải là "khối", các hệ thống tệp đó không dựa trên khối). Điều đó đang được nói, điều này không có nghĩa là dễ dàng tìm thấy nơi dữ liệu cũ sống và làm điều đó trước khi không gian được tái chế. Vì vậy, câu trả lời của bạn, không, vẫn đúng
Celada

@Celada Cảm ơn! Tôi thấy rằng rất nhiều thông tin. Tôi đã không có thời gian để xem cách btrfs hoặc zfs hoạt động, nhưng tôi biết chúng tồn tại.
Thủy thủ

2

Đảm bảo bạn có đủ dung lượng đĩa trong / var / tmp hoặc ở đâu đó lớn.

Thử

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

trong đó / dev / sda1 sẽ là đĩa của bạn trên hệ thống của bạn.

Sau đó tìm kiếm tập tin my-recovery-cho chuỗi của bạn.

có thể chủ yếu có mặt ở đó, Nếu bạn tìm thấy nó kiểm tra xem có thiếu linespaces, khung, sysmbols, vv

Sử dụng một từ tìm kiếm từ tệp của bạn khá kỳ lạ hoặc chuỗi sẽ cắt giảm lượng dữ liệu trong tệp. Nếu bạn tìm kiếm một từ như "echo", bạn sẽ nhận được vô số chuỗi vì hệ thống sẽ có rất nhiều tệp có từ echo trong đó.


0

Tôi đã ghi đè một tệp văn bản (VQ1.txt) với dữ liệu thử nghiệm trị giá 12 giờ :( Một khái niệm unix lưu phiên bản trước của tệp ở định dạng text.txt ~, khiến tôi xem xét thư mục chứa tệp được ghi đè với $ -ll Full danh sách hiển thị VQ1.txt ~ có dữ liệu 'bị mất' của tôi!

$ 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

4
Không phải đó là một tính năng của các trình soạn thảo văn bản nhất định thay vì Unix nói chung sao? Tôi không biết hệ thống tệp lưu các phiên bản cũ của tệp theo cách đó.
Joey

0

TL; DR - Nếu tệp bị ghi đè vẫn đang được mở bởi một quy trình đang chạy, thì bài đăng trên blog này có thể lưu thịt xông khói của bạn:

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

Trong đó, nó nói về các tệp đã bị xóa , nhưng tôi đã may mắn với nó ngay cả với một tệp được ghi đè bởi rsync. Và tôi đang nói về một tệp 60 GB được ghi đè bởi một tệp 4 MB và tôi đã có thể khôi phục bản gốc vì may mắn là tôi đã không dừng quá trình chạy đang giữ cho nó mở.

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.