ลบ / bin โดยไม่ตั้งใจ ฉันจะเรียกคืนได้อย่างไร


91

binผมทำงานในไดเรกทอรีชื่อ หลังจากที่ฉันทำเสร็จแล้วเนื่องจากความเป็นเจ้าของbinและไฟล์บางไฟล์ที่อยู่ภายในฉันจึงรันโดยไม่ตั้งใจ:

sudo rm -r /bin

แทน:

sudo rm -r bin

ดูเหมือนว่ามือของฉันเคยเพิ่ม/ด้านหน้าของทุกสิ่งที่ฉันพิมพ์

ฉันจะคืนค่า/binไดเรกทอรีของฉันได้อย่างไร

ฉันต้องการไฟล์เดียวกันกับที่เป็น Ubuntu ฉันไม่ต้องการคัดลอกและวางจากดิสก์สดหรือระบบอื่นที่ใช้งานอยู่


3
ไม่ได้/binอยู่ใน Ubuntu เพียงแค่ symlink ใน/usr/binวันนี้ ดังนั้นสิ่งที่คุณต้องทำคือใส่ symlink กลับมา?
Muzer

3
@Muzer ฉันทำงาน 16.04 และ/binไม่ได้เป็น symbolic link ไปที่นี่ผมคิดว่าจะเป็นกับ/usr/bin FHSถ้าเราตรวจสอบแพคเกจเล็ก ๆ น้อย ๆ เช่นcoreutilsใน(ที่นี่)zesty เราสามารถเห็นสิ่งต่าง ๆ มากมายที่จะติดตั้งใน/binข้างๆ/usr/binแต่ก็ยังสามารถเป็นลิงก์ได้ฉันไม่ทราบ
Ravexina

2
@Ravexina Arch Linux แล้วเชื่อมโยง / bin ไปยัง / usr / bin เรียบร้อยแล้ว
Dmitry Kudriavtsev

1
ฉันคิดว่าผู้คนจะตระหนักว่ามันเป็นสถานการณ์ที่เกิดขึ้นฉันไม่ได้ลบออกจริง ๆ/binฉันพิจารณาสิ่งที่อาจเกิดขึ้นกับคนอื่น (จากคำถามอื่นที่ฉันตอบ) จากนั้นฉันเขียนคำแนะนำเพื่อแบ่งปันความรู้ของฉัน กับคนอื่น ๆ :) แม้ว่าฉันจะขอบคุณความคิดเห็นทั้งหมดพวกเขายังเป็นประโยชน์กับคนอื่น ๆ ที่มาอ่านคำถามนี้ ขอขอบคุณทุกท่าน;)
Ravexina

1
ฉันได้รับนิสัยเมื่อใดก็ตามที่ฉันใช้คำสั่ง "rm -r" หรือคำสั่งอื่น ๆ ที่อาจมีผลกระทบอย่างมีนัยสำคัญฉันพิมพ์คำสั่งและจากนั้นให้มือของฉันออกจากแป้นพิมพ์อย่างน้อย 3 วินาทีก่อนที่จะกดปุ่ม ENTER นั่นทำให้ฉันมีโอกาสได้ดูมันและทำให้แน่ใจว่าฉันมีทุกอย่างที่พิมพ์อย่างถูกต้องและฉันรู้ว่ามันจะทำอะไรในสิ่งที่ฉันวางแผนจะทำ ในโอกาสที่หายากระหว่างหยุดชั่วคราวฉันตัดสินใจว่าฉันจะต้องลบคำสั่ง - ไม่ใช่เพราะมันเป็นคำสั่งที่ผิด แต่บางครั้งก็เพราะฉันต้องทำการยืนยันก่อน
ajb

คำตอบ:


180

เป็นไปได้ไหม?

มีการติดตั้งยูทิลิตี้เล็ก ๆ น้อย ๆ ที่สำคัญและสำคัญ/binและตอนนี้คุณก็ไม่สามารถเข้าถึงสิ่งเหล่านี้ ความจริงแล้วถ้าคุณรีบูทระบบของคุณจะไม่สามารถบู๊ตได้อีกต่อไป

อย่างไรก็ตามเราจะแก้ไขปัญหาและสร้าง/binเนื้อหาให้ใกล้เคียงกับที่เป็นมากที่สุด ความแตกต่างเพียงอย่างเดียวคือลิงก์สัญลักษณ์ที่เราจะแก้ไขด้วย


อย่างไร?

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

ตัวอย่างเช่นหลังจากchrootนั้นเราจะได้รับรายการแพคเกจที่ติดตั้งไฟล์ในการ/binใช้งาน:

dpkg --search /bin | cut -f1 -d: | tr ',' '\n'

และเรายังสามารถใช้:

dpkg --listfiles PACKAGE-NAME | grep "^/bin/" # or awk '$0 ~ "^/bin/

/binที่จะแสดงรายการไฟล์ที่ติดตั้งโดยแพคเกจเหล่านี้ใน

จากนั้นเราก็สร้างรายการแพคเกจทั้งหมดที่จำเป็นสำหรับเราจากนั้นดาวน์โหลดพวกเขาและแตกไฟล์ออกมา/binด้วยสิ่งต่อไปนี้:

xargs apt download < list-packages
dpkg-deb -x PACKAGE .
mv ./bin/* /bin

อย่างไรก็ตามเราต้องใช้สคริปต์เพื่อตรวจสอบแพ็กเกจที่ติดตั้งไว้ทั้งหมดในระบบของเราเพราะการทำมันด้วยตนเองเป็นเพียงความบ้าคลั่ง

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

สกรีนช็อตของรายการแพคเกจ <code> / bin </code> เป็นเอาต์พุตโดยสคริปต์ของฉัน

ในตอนท้ายเราเลือกที่จะติดตั้งแพ็คเกจทั้งหมดหรือดาวน์โหลดและแตกไฟล์ที่จำเป็นไปยัง/bin(ซึ่งเป็นตัวเลือกที่แนะนำ):

ภาพหน้าจอของตัวเลือกที่กำหนดโดยสคริปต์ของฉัน

คุณสามารถคว้าสำเนาของสคริปต์นี้หรือดาวน์โหลดได้โดยตรง


เริ่มกันเลย

chroot

บู๊ตระบบของคุณด้วยดิสก์สดที่มีสถาปัตยกรรมเดียวกับอูบุนตูที่คุณติดตั้งเปิดเทอร์มินัลและรับสิทธิ์การเข้าถึงรูท:

sudo -i

เมานต์rootระบบไฟล์ของคุณ(สำหรับฉันแล้ว/dev/sda1):

mount /dev/sda1 /mnt

เราจะต้องเชื่อมต่อกับอินเทอร์เน็ตดังนั้นคัดลอกresolv.confจาก Ubuntu สดไปยังพาร์ทิชันรูทที่ติดตั้งของคุณ:

cp /etc/resolv.conf /mnt/etc/resolv.conf

ตอนนี้คัดลอกสคริปต์ไปยังบางที่บนพาร์ติชันที่เมาท์เช่น:

cp /media/ubuntu/usb/restore-bin.sh /mnt/restore-bin.sh

หรือคุณสามารถดาวน์โหลดโดยใช้wgetเป็นต้นเช่น:

wget https://git.io/v9fRm -O /mnt/restore-bin.sh

ติดตั้งเส้นทางที่จำเป็นอื่น ๆ :

mount --bind /dev /mnt/dev
mount --bind /sys /mnt/sys
mount -t proc /proc /mnt/proc

และนี่คือความแตกต่างเล็กน้อย : เราchrootจะไปยังระบบที่เสียหายได้อย่างไรเมื่อไม่มี/binไดเรกทอรีอยู่ในนั้น? เราควรใช้เชลล์ตัวไหน

ดังนั้นสร้างไดเรกทอรีช่องเก็บชั่วคราว เช่น: ตั้งชื่อbintmpภายในรูทระบบที่ใช้งานไม่ได้:

mkdir /mnt/bintmp

จากนั้นผูกชีวิต/binลงในที่:

mount --bind /bin /mnt/bintmp

Chroot เข้าสู่ระบบในขณะที่ตั้ง/bintmp/bashเป็นเปลือกเข้าสู่ระบบของคุณ:

chroot /mnt /bintmp/bash

ส่งออกตัวแปรสภาพแวดล้อม/bintmpของคุณPATH:

export PATH=/bintmp:$PATH

ให้สคริปต์บิตที่ปฏิบัติการได้:

chmod +x restore-bin.sh

เรียกใช้สคริปต์:

./restore-bin.sh

รอให้การค้นหาเสร็จสมบูรณ์จากนั้นตอบคำถามที่เราเห็นในภาพหน้าจอ มันจะเริ่มคืนค่า/binและเราเกือบเสร็จแล้ว

หลังจากเสร็จสิ้นให้ใช้CTRL+ Dเพื่อออกจากchrootสภาพแวดล้อมและยกเลิกการต่อเชื่อมเส้นทางที่เมานต์:

umount -R /mnt

รีบูทระบบ

กู้คืนลิงก์ภายใน /bin

ตอนนี้เกือบทั้งหมดของไฟล์ภายใน/binไดเรกทอรีจะกลับมายกเว้นการเชื่อมโยงประมาณ 5 update-alternativesสัญลักษณ์ที่มีการจัดการโดย

ในระบบที่รันอยู่ให้รัน:

sudo update-alternatives --all

มันถามคำถามคุณ คุณสามารถกดENTERเพื่อยอมรับพวกเขาทั้งหมด

และตอนนี้เราเสร็จแล้ว


30
นี่คือคำตอบที่ดีที่สุดที่ฉันเคยเห็นใน Ask Ubuntu เป็นเรื่องที่ดีมาก ๆ ที่คุณต้องทำงานหนักเพื่อให้รู้ว่า OP อยู่ในสถานการณ์ที่ไม่สะดวก
Nonny Moose

15
โอ้เดี๋ยวก่อน tl; dr. ฉันควรตระหนักว่าคุณทำอย่างนั้น
Nonny Moose

มันอัศจรรย์มาก. ฉันชอบที่การออกแบบ SE ไม่ให้คำใบ้ใด ๆ เลยว่านี่เป็นคำถามที่ตอบเอง
Pedro A

5
@Hamsteriffic มัน: เห็นรูปสี่เหลี่ยมผืนผ้าที่มีชื่อของผู้ตอบ (ลายเซ็น): มันมีพื้นหลังสีเข้มกว่า, ซึ่งโพสต์ไม่ได้ทำโดย OP สิ่งนี้ใช้กับความคิดเห็นคำตอบและคำถาม
Ruslan

27

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


เนื่องจากคุณมีกระสุนทำงานอยู่แล้วและตั้งแต่sudoนั้น/usr/binมาเราจะได้รูทเชลล์ที่ทำงานอยู่ก่อนที่เราจะทำความเสียหายเพิ่มเติม แต่/bin/bashและกระสุนอื่น ๆ ส่วนใหญ่หายไป! โชคดีที่ Linux ยังมีสำเนาเชลล์ในหน่วยความจำที่คุณใช้อยู่ ดังนั้น:

sudo /proc/$$/exe

การพูดอย่างเคร่งครัดเราไม่ต้องการรูทเชลล์สำหรับสิ่งต่อไปนี้ แต่อย่างไรก็ตาม.

ตอนนี้dpkgยังใช้งานได้อย่างน้อยสำหรับการค้นหาแพ็คเกจที่มีไฟล์ใน/bin:

dpkg -S /bin

เราสามารถใช้awkในการประมวลผลและรับชื่อแพ็คเกจและxargsและapt-getเพื่อดาวน์โหลดแพ็คเกจ (ทั้งหมดใน/usr/bin) หากคุณมีไดเรกทอรีชั่วคราวที่คุณสามารถใช้ได้cdนั่นเพราะไดเรกทอรีปัจจุบันของคุณกำลังจะยุ่งหน่อย:

dpkg -S /bin | awk -F '[, :]' '{NF--}1' | xargs apt-get download

ตอนนี้ปัญหาที่ใหญ่ที่สุดที่เรามีคือ/bin/tarมันขาดหายไปและหากไม่มีมันก็dpkgไม่สามารถแยกไฟล์เก็บถาวรได้ เราสามารถรับได้สองในสามของที่นั่นเพราะ:

  1. .debไฟล์เป็นที่arเก็บถาวรจริง ๆ(อีกครั้งใน/usr/bin):

    ar x tar_*.deb
    
  2. ประกอบด้วย.tar.*คลังเก็บสองแห่งdataและcontrol:

    $ echo *.tar.*
    control.tar.gz data.tar.xz
    
  3. ในขณะที่ระบบสาธารณูปโภค gzip อยู่ใน/bin, unxzอยู่ใน/usr/bin:

    unxz data.tar.xz
    

ตอนนี้เรามีdata.tarไฟล์ที่ไม่ต้องtarแยกtarออกจากมัน

Python เพื่อช่วยเหลือ ! นี่คือที่sudoต้องการจริงๆ:

$ sudo python -c 'import tarfile; tarfile.open("data.tar").extractall("/")'
$ echo /bin/*
/bin/tar

ตอนนี้เราสามารถใช้dpkgเพื่อแตกไฟล์ deb ที่เหลือเพื่อให้สมบูรณ์/bin:

for i in *.deb; do dpkg-deb -x "$i" /; done

อย่างไรก็ตามเราควรทำการติดตั้งไฟล์ deb อย่างเหมาะสมดังนั้น symlink เป็นต้นที่จะถูกสร้างโดยแพ็คเกจนั้นถูกสร้างขึ้นใหม่:

sudo apt install --reinstall ./*.deb

หรือ:

sudo dpkg -i *.deb
sudo apt-get install -f

หมายเหตุ:

  1. เราไม่สามารถใช้ Python 2 เพื่อแยกdata.tar.xzไฟล์โดยตรงเนื่องจาก Python 2 รองรับเฉพาะการบีบอัด gzip และ bzip2 อย่างไรก็ตาม Python 3 รองรับมันดังนั้นคุณสามารถใช้ Python 3 ได้โดยตรงโดยไม่ต้องunxz:

    sudo python3 -c 'import tarfile; tarfile.open("data.tar.xz").extractall("/")'
    
  2. หลังจากกลับมา/bin/tarแล้วคุณยังต้องแตกไฟล์ deb บางส่วนก่อนจึงจะสามารถใช้งานได้apt-get: เชลล์, coreutils ฯลฯ ง่ายกว่าที่จะแยกไฟล์ทั้งหมดและติดตั้งใหม่ในภายหลัง

ฉันไม่ได้ทดสอบ แต่ฉันเกือบจะอ่านมันอย่างสมบูรณ์มันยอดเยี่ยมจริง ๆ แล้วฉันพยายามค้นหาสำเนาทุบตีในความทรงจำฉันค้นหานิดหน่อยฉันไม่พบสิ่งที่น่าสนใจและหลังจากที่ฉันเห็น tar นั้น ไม่ได้อยู่/usr/binฉันพูดอะไรก็ตามที่ฉันไปด้วย chroot ... เยี่ยมยอด
Ravexina

1
คำถามไม่ใช่/proc/$$/exeลิงค์ไปยัง/bin/bash? มันทำงานอย่างไรเมื่อ/binถูกลบ? (มันใช้งานได้ แต่เป็นอย่างไร) ฉันคิดว่ามันควรจะเป็นลิ้งค์ขาด ... นั่นคือสาเหตุที่ฉันทิ้งความคิดนี้ไว้เบื้องหลัง
Ravexina

3
@Ravexina ไม่ได้รับคำตอบที่สมบูรณ์ แต่: / proc / <pid> / exe symlink แตกต่างจาก symlink ทั่วไปอย่างไร
muru

1
PATH = / usr / lib / klibc / bin: $ PATH จะนำแมวและกลับมาอยู่ในเส้นทางของคุณ
Joshua

@ โจชัวและพวกเขาทุกคนเชื่อมโยงแบบคงที่! ดี!
muru

7

คุณสามารถชั่วคราวใส่ไฟล์จากซีดีสดหรือระบบอื่นเข้ามาในของคุณ/binจะทำให้ระบบของคุณสามารถใช้งานได้แล้วแทนที่ด้วยไฟล์จากการติดตั้งอูบุนตูของคุณโดยใช้สำหรับแพคเกจที่มีสิ่งที่อยู่ในapt-get install --reinstall/bin


นี่คือสิ่งที่ฉันจะทำ ดีวีดีสดที่มีหมายเลขเวอร์ชันเดียวกันเกือบจะเหมือนกันหากไม่ตรงกับการติดตั้งในปัจจุบัน หากฉันมีแผ่นดิสก์หรือรุ่น USB Live ฉันสามารถเปรียบเทียบพวกเขาและโพสต์คำตอบเช่นคุณ หัวข้อนี้เป็นทฤษฎีมากกว่าถ้า OP ไม่เคยลบ / bin ในตอนแรกซึ่งเป็นไปได้ในขณะที่เขาเขียนคำตอบในเวลาเดียวกันกับคำถามในทุกโอกาส การทดลองทางความคิดยังดีมากและสไตล์การเขียนที่ยอดเยี่ยม
WinEunuuchs2Unix

ฉันขอแนะนำให้แก้ไขคำตอบนี้เพื่อขยายโดยมีรายละเอียดเฉพาะเกี่ยวกับวิธีการทำเช่นนี้ (ดูเพิ่มเติมฉันจะเขียนคำตอบที่ดีได้อย่างไรสำหรับคำแนะนำทั่วไปเกี่ยวกับคำตอบประเภทใดที่ถือว่ามีค่ามากที่สุดใน AskUbuntu)
David Foerster

1

เพิ่มเติมบางอย่างเพื่อคำตอบที่ดีเยี่ยมนี้หลังจากที่ผมพบปัญหานี้ (พร้อมกับลบ/boot, /etc, /libและ/lib64):

  • chrootต้องการ/libและ/lib64เป็นปัจจุบัน; มิฉะนั้นคุณจะได้รับข้อผิดพลาดต่อไปนี้:
    failed to run command ‘/bin/bash’: No such file or directory
    ฉันคัดลอกสิ่งเหล่านี้จาก LiveCD OS และไม่มีปัญหาในการกู้คืน YMMV ขึ้นอยู่กับแพ็คเกจที่คุณติดตั้งบนระบบ
  • ฉันไม่สามารถแก้ไขคำตอบที่อ้างถึงข้างต้น แต่มีคำที่พิมพ์ผิด:
    cp /etc/resolv.conf /mnt/etc/resolv.cof
    ควรเป็น
    cp /etc/resolv.conf /mnt/etc/resolv.conf
  • /bootสามารถเรียกคืนได้อย่างง่ายดายโดยใช้เครื่องมือด้วง ดูที่นี่
  • ในฐานะที่เป็นคำตอบนี้แนะนำapt install --reinstall <package>เป็นวิธีที่ดีเพื่อเรียกคืนไฟล์ที่หายไป/bin, และ /lib/lib64
    • แพคเกจบางอย่างที่จำเป็นต้องมีการติดตั้งใหม่: libaio1, mysql-server, openvpn,vsftpd

หมายเหตุถึงตนเอง:
rm -rf folder /*ไม่เหมือนกับrm -rf folder/*

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