สามารถกู้คืนไฟล์ที่เขียนทับได้หรือไม่


42

ฉันไม่ได้พูดถึงการกู้คืน ไฟล์ที่ถูกลบแต่เป็นไฟล์ที่ถูกเขียนทับ คือโดยวิธีการดังต่อไปนี้:

# move
mv new_file old_file

# copy
cp new_file old_file

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

เป็นไปได้หรือไม่ที่จะเรียกคืนข้อมูลใด ๆ หากดำเนินการข้อใดข้อหนึ่งจากสามข้อข้างต้นหากไม่มีการติดตั้งโปรแกรมพิเศษบนเครื่อง linux?


4
คุณหมายถึงนอกเหนือจากการสำรองข้อมูลของคุณ?
jasonwryan

@ Jasonwryan ใช่แน่นอน
คำถามล้นเมื่อ

2
ฉันแค่ต้องการชี้ให้เห็นว่าตัวอย่างแรกของคุณ ( mv) คล้ายกับการลบold_fileไม่ใช่การเขียนทับดังนั้นวิธีการ (ถ้ามี) สำหรับการกู้คืนไฟล์ที่ถูกลบซึ่งตรงข้ามกับไฟล์ที่ถูกเขียนทับจะมีผลในกรณีนั้น อีกสองตัวอย่างของคุณเขียนทับที่มีอยู่แล้วold_fileและexisting_fileตามลำดับ
Celada

ตัวอย่างทั้งสามที่คุณระบุมีการใช้งานโดยการลบบล็อคข้อมูลของไฟล์ต้นฉบับทั้งหมดและเขียนไปยังบล็อกที่จัดสรรใหม่และขั้นตอนสำหรับการกู้คืนข้อมูลนั้นเหมือนกับการกู้คืนไฟล์ที่ถูกลบ อาจมีข้อยกเว้นหากไฟล์ต้นฉบับสั้นมาก (สั้นกว่า 60 ไบต์ต่อ ext4) ซึ่งสองตัวอย่างหลังอาจทำให้ข้อมูลก่อนหน้าไม่สามารถกู้คืนได้
Mark Plotnick

1
@ MarkPlotnick ตามความคิดเห็นของ Celada mvนั้นแตกต่างกัน
คำถามล้นเมื่อ

คำตอบ:


59

คำตอบคือ "อาจใช่ แต่ขึ้นอยู่กับประเภทของระบบไฟล์และเวลา"

ไม่มีตัวอย่างทั้งสามที่จะเขียนทับบล็อกข้อมูลทางกายภาพของ old_file หรือ existing_file ยกเว้นโดยบังเอิญ

  • mv new_file old_file. นี่จะเป็นการยกเลิกการเชื่อมโยงไฟล์เก่า หากมีฮาร์ดลิงก์เพิ่มเติมไปยัง old_file บล็อกจะยังคงไม่เปลี่ยนแปลงในลิงก์ที่เหลือเหล่านั้น มิฉะนั้นบล็อกจะโดยทั่วไป (ขึ้นอยู่กับประเภทของระบบไฟล์) จะถูกวางในรายการฟรี จากนั้นหากmvต้องการคัดลอก (ตรงข้ามกับการย้ายรายการไดเรกทอรี) บล็อกใหม่จะถูกจัดสรรเป็นการmvเขียน

    บล็อกเหล่านี้เพิ่งได้รับการจัดสรรอาจหรือไม่อาจจะเป็นคนเดียวกับที่เป็นอิสระเพียง บนระบบไฟล์เช่นUFSบล็อกจะถูกจัดสรรหากเป็นไปได้จากกลุ่มรูปทรงกระบอกเดียวกับไดเรกทอรีที่ไฟล์ถูกสร้างขึ้นดังนั้นจึงมีโอกาสที่การยกเลิกการเชื่อมโยงไฟล์จากไดเรกทอรีและสร้างไฟล์ในไดเรกทอรีเดียวกันนั้นจะใช้งานอีกครั้ง ( และเขียนทับ) บล็อกเดียวกันบางส่วนที่เพิ่งถูกปล่อยให้เป็นอิสระ นี่คือเหตุผลที่คำแนะนำมาตรฐานสำหรับผู้ที่ลบไฟล์โดยไม่ตั้งใจคือไม่เขียนข้อมูลใหม่ไปยังไฟล์ในแผนผังไดเรกทอรี (และไม่ควรไปที่ระบบไฟล์ทั้งหมด) จนกว่าผู้ใช้จะสามารถกู้คืนไฟล์ได้

  • cp new_file old_fileจะทำสิ่งต่อไปนี้ (คุณสามารถใช้straceเพื่อดูการเรียกของระบบ):

    เปิด ("old_file", O_WRONLY | O_TRUNC) = 4

    การตั้งค่าสถานะ O_TRUNC จะทำให้บล็อกข้อมูลทั้งหมดเป็นอิสระเช่นเดียวกับที่mvได้ทำข้างต้น และตามข้างต้นพวกเขามักจะถูกเพิ่มลงในรายการฟรีและอาจหรือไม่อาจถูกนำมาใช้ซ้ำโดยการเขียนที่ตามมาทำโดยcpคำสั่ง

  • vi existing_file. ถ้าviเป็นจริงvimที่:xคำสั่งไม่ต่อไปนี้:

    unlink ("existing_file ~") = -1 ENOENT (ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว)
    เปลี่ยนชื่อ ("existing_file", "existing_file ~") = 0
    open ("existing_file", O_WRONLY | O_CREAT | O_TRUNC, 0664) = 3

    ดังนั้นจึงไม่ได้ลบข้อมูลเก่า ข้อมูลจะถูกเก็บไว้ในไฟล์สำรอง

    ใน FreeBSD viทำopen("existing_file",O_WRONLY|O_CREAT|O_TRUNC, 0664)เช่นนั้นซึ่งจะมีความหมายเช่นเดียวกับcpข้างต้น


คุณสามารถกู้คืนข้อมูลบางส่วนหรือทั้งหมดได้โดยไม่ต้องใช้โปรแกรมพิเศษ ทั้งหมดที่คุณต้องการgrepและddและการเข้าถึงอุปกรณ์ดิบ

สำหรับไฟล์ข้อความขนาดเล็กgrepคำสั่งเดียวในคำตอบจาก @Steven Dในคำถามที่คุณลิงก์ไปนั้นเป็นวิธีที่ง่ายที่สุด:

grep -i -a -B100 -A100 'text in the deleted file' /dev/sda1

แต่สำหรับไฟล์ที่มีขนาดใหญ่กว่าซึ่งอาจอยู่ในบล็อกที่ไม่ต่อเนื่องหลายชุดฉันจะทำสิ่งนี้:

grep -a -b "text in the deleted file" /dev/sda1
13813610612:this is some text in the deleted file

ซึ่งจะให้ออฟเซ็ตเป็นไบต์ของบรรทัดที่ตรงกัน ทำตามนี้ด้วยชุดddคำสั่งเริ่มต้นด้วย

dd if=/dev/sda1 count=1 skip=$(expr 13813610612 / 512)

คุณต้องการอ่านบล็อกก่อนและหลังบล็อกนั้นด้วย บน UFS บล็อกไฟล์โดยทั่วไปคือ 8KB และมักจะจัดสรรอย่างต่อเนื่องค่อนข้างบล็อกของไฟล์เดียวถูก interleaved สลับกับบล็อก 8KB จากไฟล์อื่นหรือพื้นที่ว่าง ส่วนท้ายของไฟล์บน UFS มีมากถึง 7 1KB แฟรกเมนต์ซึ่งอาจหรือไม่ต่อเนื่องกันก็ได้

แน่นอนว่าระบบไฟล์ที่บีบอัดหรือเข้ารหัสข้อมูลการกู้คืนอาจไม่ตรงไปตรงมา


มียูทิลิตี้น้อยมากใน Unix ที่จะเขียนทับบล็อคข้อมูลของไฟล์ที่มีอยู่ dd conv=notruncหนึ่งที่อยู่ในใจคือ shredอีกประการหนึ่งคือ


3
ขอบคุณสำหรับการอธิบายกลไกภายในของการปฏิบัติการทั้งสามที่แตกต่างกัน มันมีประโยชน์จริง ๆ !
คำถามล้นเมื่อ

btrfsมีความยืดหยุ่นในการลบไฟล์ มันมีแนวโน้มที่จะใช้บล็อกในลักษณะวนรอบดังนั้นถ้าคุณมีพื้นที่เพียงพอในอุปกรณ์ไฟล์จะไม่ถูกเขียนทับเป็นเวลานาน ดูที่นี่
pqnet

ทำอย่างไรถึงจะได้บล็อกที่มีมาก่อนและข้ามไปทำอะไร?
unixit

@Islam เมื่อคุณให้skip=พารามิเตอร์จากนั้นแทนที่จะอ่านจากจุดเริ่มต้นของอินพุตมันจะข้ามจำนวนบล็อกนั้น บล็อกคือ 512 ไบต์โดยค่าเริ่มต้น แต่สามารถเปลี่ยนแปลงได้ด้วยbs=พารามิเตอร์
Mark Plotnick

1
@Islam หากต้องการบล็อกข้อความก่อนหน้านี้ฉันขอแนะนำให้ระบุskip=ค่าที่น้อยกว่า 1 บล็อก (512 ไบต์) $(expr 13813610612 / 512 - 1)ในตัวอย่างของฉัน หากไม่ได้รับสิ่งที่คุณต้องการลองอีกครั้งในขณะที่ลบ 16 หรือ 32 ซึ่งจะดูพื้นที่ที่น้อยกว่า 8192 และ 16384 ไบต์ ไฟล์มักจะถูกจัดสรรในกลุ่ม 8192- ไบต์ หากคุณพยายามกู้คืนไฟล์ที่มีขนาดใหญ่ขึ้นให้ลองนับจำนวนมากขึ้นเพื่อประหยัดเวลา ฉันมักจะใช้count=16และดูผลลัพธ์ในโปรแกรมแก้ไขemacsซึ่งไม่เป็นไรถ้าข้อมูลบางอย่างไม่ใช่ข้อความ
Mark Plotnick

6

ฉันจะบอกว่าไม่ได้ (มีเครื่องหมายดอกจันขนาดยักษ์)

คิดเกี่ยวกับวิธีการวางข้อมูลบนดิสก์ คุณมีบล็อกที่มีข้อมูลและชี้ไปที่บล็อกถัดไป (ถ้ามี)

เมื่อคุณเขียนทับข้อมูลที่คุณกำลังเปลี่ยนเนื้อหาบล็อก (และถ้าคุณจะขยายไฟล์เครื่องหมายสิ้นสุดทั้งหมด) ดังนั้นอะไรที่ควรจะสามารถที่จะได้รับคืน (ดูด้านล่าง)

หากคุณตัดทอนไฟล์ให้สั้นลงแสดงว่าคุณสูญเสียบล็อกเก่าและบล็อกเหล่านั้นจะถูกรีไซเคิลในไม่ช้า หากคุณเป็นโปรแกรมเมอร์ให้คิดถึงรายการที่เชื่อมโยงซึ่งคุณ "เสีย" ครึ่งหนึ่งของรายการโดยไม่ทำการลบ / ทำ ข้อมูลนั้นยังคงอยู่ แต่โชคดีในการค้นหา

สิ่งที่น่าสนใจคือการแยกส่วน

การแตกแฟรกเมนต์เกิดขึ้นเมื่อคุณมี "ช่อง" ของข้อมูลที่ไม่ต่อเนื่องกันบนดิสก์ของคุณซึ่งอาจเกิดจากการแก้ไขไฟล์เช่นที่คุณขยายหรือย่อให้สั้นลงและจะไม่พอดีกับจุดดั้งเดิมบนดิสก์อีกต่อไป

ในกรณีที่มีไฟล์โตเกินขนาดดั้งเดิม (ต้องย้ายที่จุดนี้) ขึ้นอยู่กับระบบไฟล์ของคุณคุณสามารถคัดลอกไฟล์ทั้งหมดไปยังตำแหน่งใหม่ที่ยังมีข้อมูลเก่าอยู่ (แต่ทำเครื่องหมายว่าว่าง) หรือคุณเพียงแค่เปลี่ยนตัวชี้สิ้นสุดเก่าและให้มันชี้ไปที่ตำแหน่งใหม่ (ซึ่งจะนำไปสู่การ thrashing)

เรื่องสั้นสั้นข้อมูลของคุณอาจหายไป (โดยไม่ต้องผ่านกระบวนการทางนิติวิทยาศาสตร์ขั้นสุดขีดที่คุณดูภายใต้กล้องจุลทรรศน์); อย่างไรก็ตามมีโอกาสที่จะยังคงอยู่ที่นั่น


1
คำตอบของคุณทำให้สมมุติว่าระบบไฟล์ที่ไม่ใช่การคัดลอก -on-on-block เช่นext4หรือxfsมีการใช้งาน ด้วยการคัดลอกระบบไฟล์เขียนเช่นzfsและbtrfsในความเป็นจริงคุณไม่เคย "เปลี่ยนเนื้อหาของบล็อก"; ระบบไฟล์เหล่านั้นใช้บล็อกใหม่เอี่ยมเสมอเพื่อเก็บข้อมูลใหม่ นอกจากนี้ระบบไฟล์ที่ใช้บันทึกเช่นjffs2ยังเขียนข้อมูลใหม่ไปยังตำแหน่งใหม่เสมอ (ไม่ใช่ "บล็อก" ระบบไฟล์เหล่านั้นไม่ได้ใช้บล็อก) ดังที่ได้กล่าวมานี้ไม่ได้หมายความว่าจะหาได้ง่ายว่าข้อมูลเก่าอยู่ที่ใดและทำก่อนที่จะมีการรีไซเคิลพื้นที่ ดังนั้นคำตอบของคุณซึ่งไม่ถูกต้องยังคงถูกต้อง
Celada

@ Celada ขอบคุณ! ฉันพบว่ามีข้อมูลมาก ฉันไม่มีเวลาดูว่า btrfs หรือ zfs ทำงานอย่างไร แต่ฉันรู้ว่ามันมีอยู่จริง
SailorCire

2

ตรวจสอบให้แน่ใจว่าคุณมีพื้นที่ดิสก์เพียงพอใน / var / tmp หรือที่ใดที่หนึ่งที่ใหญ่

ลอง

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

โดยที่ / dev / sda1 จะเป็นดิสก์ของคุณในระบบของคุณ

จากนั้นค้นหาสตริงที่ฉันกู้คืนเพื่อหาคุณ

มันอาจจะเป็นส่วนใหญ่จะมีหากคุณพบว่ามันหายไปตรวจสอบ linespaces, วงเล็บ sysmbols ฯลฯ

ใช้คำค้นหาจากไฟล์ของคุณที่ค่อนข้างไม่ฉลาดหรือสตริงที่จะลดปริมาณข้อมูลในไฟล์ หากคุณค้นหาคำเช่น "echo" คุณจะได้รับสตริงกลับมามากมายเนื่องจากระบบจะมีไฟล์จำนวนมากที่มีคำว่า echo อยู่


0

ฉันเขียนทับไฟล์ข้อความ (VQ1.txt) ด้วยข้อมูลการทดสอบ 12 ชั่วโมงซึ่งมีค่า :( ความคิดที่ว่ายูนิกซ์บันทึกไฟล์เวอร์ชันก่อนหน้าในรูปแบบ text.txt ~ ทำให้ฉันมองเข้าไปในโฟลเดอร์ที่มีไฟล์ที่เขียนทับด้วย $ -ll เต็ม รายการแสดง VQ1.txt ~ ที่มีข้อมูล 'สูญหาย' ของฉัน!

$ 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
นั่นไม่ใช่คุณสมบัติของโปรแกรมแก้ไขข้อความบางอย่างแทนที่จะเป็น Unix โดยทั่วไปใช่ไหม ฉันไม่ทราบถึงระบบไฟล์ที่บันทึกไฟล์เวอร์ชันเก่าด้วยวิธีนี้
Joey

0

TL; DR - หากไฟล์ที่ถูกเขียนทับยังคงถูกเปิดค้างอยู่โดยกระบวนการที่ทำงานโพสต์บล็อกนี้อาจบันทึกเบคอนของคุณ:

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

ในนั้นมันพูดถึงไฟล์ที่ถูกลบแต่ฉันโชคดีแม้ว่ามันจะเป็นไฟล์ที่ถูกเขียนทับโดย rsync และฉันกำลังพูดถึงไฟล์ 60 GB ที่เขียนทับโดย 4 MB หนึ่งและฉันสามารถกู้คืนต้นฉบับได้เพราะโชคดีที่ฉันไม่ได้หยุดกระบวนการทำงานที่เปิดไว้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.