Vô tình loại bỏ / thùng. Làm thế nào để tôi khôi phục nó?


91

Tôi đã làm việc trên một thư mục có tên bin. Sau khi tôi hoàn thành, vì quyền sở hữu binvà một số tệp trong đó tôi vô tình chạy:

sudo rm -r /bin

Thay vì:

sudo rm -r bin

Có vẻ như bàn tay của tôi đã sử dụng để thêm /vào trước mọi thứ tôi gõ.

Làm thế nào tôi có thể khôi phục /binthư mục của tôi ?

Tôi muốn cùng các tệp thuộc về Ubuntu của mình, tôi không muốn sao chép và dán chúng từ đĩa trực tiếp hoặc hệ thống đang chạy khác.


3
Không phải /bintrên Ubuntu chỉ là một liên kết tượng trưng cho /usr/binnhững ngày này sao? Vì vậy, tất cả những gì bạn cần làm là đặt symlink trở lại?
Muzer

3
@Muzer Tôi đang chạy 16.04 và /binkhông phải là một liên kết tượng trưng /usr/binở đây, tôi nghĩ rằng điều đó sẽ chống lại FHS. ngoài ra nếu chúng ta kiểm tra một gói tầm thường như coreutilstrong zesty (ở đây) . chúng ta có thể thấy rất nhiều thứ sẽ được cài đặt /binbên cạnh /usr/bin, nhưng nó vẫn có thể là một liên kết, tôi không biết.
Ravexina

2
@Ravexina Arch Linux đã có symlink / bin to / usr / bin
Dmitry Kudriavtsev

1
Tôi nghĩ rằng mọi người sẽ nhận ra rằng đó là một tình huống bịa đặt, tôi đã không thực sự loại bỏ tôi /bin, tôi đã xem xét điều gì đó có thể xảy ra với bất kỳ ai khác (Dựa trên một câu hỏi khác mà tôi đã trả lời), sau đó tôi đã viết một hướng dẫn để chia sẻ kiến ​​thức của mình với những người khác :), mặc dù tôi đánh giá cao tất cả các bình luận, chúng cũng hữu ích cho những người khác đến đọc câu hỏi này. Cảm ơn tất cả các bạn;)
Ravexina

1
Tôi đã có thói quen bất cứ khi nào tôi sử dụng lệnh "rm -r" hoặc bất kỳ lệnh nào khác có thể gây hậu quả đáng kể, tôi gõ lệnh và sau đó rời tay khỏi bàn phím ít nhất khoảng 3 giây trước khi nhấn ĐI VÀO. Điều đó cho tôi cơ hội để xem qua và đảm bảo rằng tôi đã nhập mọi thứ chính xác và tôi biết nó sẽ làm những gì tôi dự định làm. Trong các trường hợp hiếm hoi, trong lần tạm dừng đó, tôi quyết định rằng tôi cần xóa lệnh - không phải lúc nào cũng vì đó là lệnh sai, nhưng đôi khi vì tôi cần thực hiện một số xác minh trước.
ajb

Câu trả lời:


180

Có thể không?

Chà, hầu hết các tiện ích tầm thường và quan trọng đều được cài đặt /bin, và bây giờ bạn mất quyền truy cập vào tất cả chúng. Thực tế, nếu bạn khởi động lại, hệ thống của bạn sẽ không thể khởi động được nữa.

Dù sao, chúng tôi sẽ khắc phục sự cố và làm cho /binnội dung của nó càng gần càng tốt với vị trí của nó. Sự khác biệt duy nhất sẽ là một số liên kết tượng trưng mà chúng tôi cũng sẽ sửa chữa.


Làm sao?

Đầu tiên, chúng ta nên chrootvào hệ thống bị hỏng của bạn, nhưng với một sự khác biệt nhỏ ! Sau đó, chúng tôi sẽ nhận được một danh sách các gói đã cài đặt trên hệ thống của bạn có bất kỳ tệp nào được cài đặt trong /binthư mục, sau đó chúng tôi sẽ chỉ tải xuống các gói cần thiết và trích xuất các tệp cần thiết vào /bin. Sau đó, chúng tôi sẽ được thực hiện.

Ví dụ: sau đó chroot, chúng ta có thể nhận được danh sách các gói đã cài đặt tệp /binbằng cách sử dụng:

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

Và chúng ta cũng có thể sử dụng:

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

để liệt kê các tập tin được cài đặt bởi các gói này trong /bin.

Sau đó, chúng tôi chỉ cần tạo một danh sách tất cả các gói cần thiết cho chúng tôi, sau đó tải xuống và trích xuất chúng /binvới một cái gì đó như:

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

Tuy nhiên, chúng tôi phải sử dụng tập lệnh để kiểm tra tất cả các gói đã cài đặt trên hệ thống của mình, vì thực hiện thủ công chỉ là sự điên rồ.

Vì vậy, tôi đã viết một kịch bản làm mọi thứ chúng ta cần. Nó tìm thấy tất cả các gói cần thiết để chúng tôi khôi phục /bin, hiển thị cho chúng tôi tên của từng gói và các tệp liên quan của chúng /bin. Đây là một ảnh chụp màn hình:

Ảnh chụp màn hình danh sách gói <code> / bin </ code> làm đầu ra theo tập lệnh của tôi

Cuối cùng, chúng tôi chọn cài đặt lại tất cả các gói hoặc chỉ tải xuống và giải nén các tệp cần thiết vào /bin(đó là tùy chọn được đề xuất):

Ảnh chụp màn hình các tùy chọn được cung cấp bởi tập lệnh của tôi

Bạn có thể lấy một bản sao của tập lệnh này hoặc tải xuống trực tiếp .


Hãy bắt đầu

chroot

Khởi động hệ thống của bạn với một đĩa trực tiếp có kiến ​​trúc giống như Ubuntu đã cài đặt của bạn, mở một thiết bị đầu cuối và nhận quyền truy cập root:

sudo -i

Gắn roothệ thống tệp của bạn (đối với tôi là /dev/sda1):

mount /dev/sda1 /mnt

Chúng tôi sẽ cần kết nối với Internet, vì vậy hãy sao chép resolv.conftừ Ubuntu trực tiếp vào phân vùng gốc được gắn kết của bạn:

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

Bây giờ sao chép tập lệnh vào một nơi nào đó trên phân vùng được gắn kết, ví dụ:

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

hoặc bạn có thể tải xuống bằng cách sử dụng wget, v.v. như:

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

Gắn các đường dẫn cần thiết khác:

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

Và đây là một sự khác biệt nhỏ : làm thế nào chúng ta có thể chrootđến một hệ thống bị hỏng khi không có /binthư mục trong đó? Chúng ta nên chạy vỏ nào?

Vì vậy, tạo một thư mục bin tạm thời. ví dụ: được đặt tên bintmptrong hệ thống gốc bị hỏng của bạn:

mkdir /mnt/bintmp

Sau đó ràng buộc cuộc sống /binvào đó:

mount --bind /bin /mnt/bintmp

Chroot vào hệ thống trong khi đặt /bintmp/bashvỏ đăng nhập của bạn:

chroot /mnt /bintmp/bash

Xuất biến /bintmpnhư PATHmôi trường của bạn :

export PATH=/bintmp:$PATH

Cung cấp cho tập lệnh bit thực thi:

chmod +x restore-bin.sh

Chạy kịch bản:

./restore-bin.sh

Đợi cho việc tìm kiếm được hoàn thành sau đó trả lời câu hỏi chúng ta đã thấy trong ảnh chụp màn hình. Nó sẽ bắt đầu khôi phục /binvà chúng ta gần như đã hoàn thành.

Sau khi hoàn thành, sử dụng CTRL+ Dđể thoát khỏi chrootmôi trường và ngắt kết nối các đường dẫn được gắn kết:

umount -R /mnt

Khởi động lại hệ thống.

Khôi phục các liên kết trong /bin

Bây giờ hầu như tất cả các tệp trong /binthư mục đã trở lại, ngoại trừ khoảng 5 liên kết tượng trưng được quản lý bởi update-alternatives.

Trong hệ thống đang chạy của bạn, hãy chạy:

sudo update-alternatives --all

Nó hỏi bạn một số câu hỏi; bạn chỉ cần nhấn ENTERđể chấp nhận tất cả.

Và bây giờ chúng ta đã hoàn thành.


30
Không còn nghi ngờ gì nữa, đây là câu trả lời hay nhất tôi từng thấy trên Ask Ubuntu. Bạn thật sự rất vui khi được làm việc rất nhiều khi biết OP đang ở trong một tình huống bất tiện.
Nonny Moose

15
Oh chờ tl; dr. Tôi nên nhận ra rằng bạn đã làm điều đó.
Nonny Moose

Thật đáng kinh ngạc. Tôi thích cách thiết kế SE không đưa ra bất kỳ gợi ý nào cả vì đây là câu hỏi tự trả lời.
Pedro A

5
@Rouletteiffic it does: xem hình chữ nhật chứa tên người trả lời (chữ ký): nó có nền tối hơn, mà các bài đăng không phải bởi OP không. Điều này áp dụng cho ý kiến, câu trả lời và câu hỏi.
Ruslan

27

Nếu hệ thống hiện tại của bạn vẫn có vỏ chạy và truy cập internet, điều này có thể được thực hiện bằng các công cụ hiện có ở nơi khác trên hệ thống. Tôi giả sử bạn chỉ xóa /bin. /bintất nhiên có tiện ích thuận tiện nhất mà bạn có thể sử dụng trong tình huống như vậy (busybox), nhưng không có điều đó, chúng ta sẽ phải có một chút sáng tạo.


Vì bạn đã có một shell shell đang chạy, và vì đã sudocó trong đó /usr/bin, chúng ta hãy tạo cho mình một shell root đang chạy trước khi chúng ta gây thêm thiệt hại. Nhưng /bin/bashvà hầu hết các vỏ khác đã biến mất! May mắn thay, Linux vẫn có một bản sao trong bộ nhớ mà bạn đang sử dụng. Vì thế:

sudo /proc/$$/exe

Nói đúng ra, chúng ta không cần một cái vỏ gốc cho phần lớn những gì tiếp theo. Nhưng dù sao.

Bây giờ, dpkgvẫn hoạt động, ít nhất là để tìm gói nào có tệp trong /bin:

dpkg -S /bin

Chúng ta có thể sử dụng awkđể xử lý nó và lấy tên gói xargsapt-gettải xuống các gói (tất cả trong /usr/bin). Nếu bạn có một thư mục tạm thời mà bạn có thể sử dụng, cdở đó, bởi vì thư mục hiện tại của bạn sẽ có một chút lộn xộn:

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

Bây giờ, vấn đề lớn nhất mà chúng tôi gặp phải /bin/tarlà thiếu, và không có nó, dpkgkhông thể trích xuất tài liệu lưu trữ. Chúng ta có thể đi được hai phần ba quãng đường tới đó, bởi vì:

  1. .debtập tin thực sự là artài liệu lưu trữ (một lần nữa trong /usr/bin):

    ar x tar_*.deb
    
  2. Bao gồm hai .tar.*tài liệu lưu trữ datacontrol:

    $ echo *.tar.*
    control.tar.gz data.tar.xz
    
  3. Trong khi các tiện ích gzip đang ở /bin, unxz/usr/bin:

    unxz data.tar.xz
    

Bây giờ chúng tôi có một data.tartập tin mà không cần tartrích xuất tartừ nó.

Python để giải cứu ! Đây là nơi sudothực sự cần thiết:

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

Bây giờ chúng ta có thể sử dụng dpkgđể trích xuất các tệp deb còn lại để hoàn thành hợp lý /bin:

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

Tuy nhiên, chúng ta vẫn nên thực hiện cài đặt đúng các tệp deb, để các liên kết tượng trưng, ​​vv sẽ được tạo bởi các gói được tạo lại:

sudo apt install --reinstall ./*.deb

Hoặc là:

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

Ghi chú:

  1. Chúng tôi không thể sử dụng Python 2 để trích xuất trực tiếp data.tar.xztệp, vì Python 2 chỉ hỗ trợ nén gzip và bzip2. Tuy nhiên, Python 3 không hỗ trợ nó, vì vậy bạn có thể sử dụng Python 3 trực tiếp mà không cần unxz:

    sudo python3 -c 'import tarfile; tarfile.open("data.tar.xz").extractall("/")'
    
  2. Sau khi quay lại /bin/tar, bạn vẫn cần trích xuất một số tệp deb trước khi có thể sử dụng apt-get: shell, coreutils, v.v. Dễ dàng hơn để chỉ trích xuất tất cả chúng và cài đặt lại sau.

Tôi đã không kiểm tra nó, nhưng tôi gần như đã đọc nó hoàn toàn, thật tuyệt vời, thực sự tôi đã cố gắng tìm một bản sao của bash trong bộ nhớ, tôi đã tìm kiếm một chút, tôi không tìm thấy bất cứ điều gì gây chú ý và sau khi tôi thấy tar đó là không vào /usr/bin, tôi nói bất cứ điều gì tôi đi với chroot ... Tuyệt vời.
Ravexina

1
Một câu hỏi, không phải /proc/$$/exelà một liên kết đến /bin/bash? Làm thế nào nó hoạt động khi /binđược gỡ bỏ? (Nó hoạt động, nhưng làm thế nào), tôi nghĩ rằng nó nên là một liên kết bị hỏng ... đó là lý do tại sao tôi bỏ qua ý tưởng này phía sau.
Ravexina

3
@Ravexina đã không nhận được câu trả lời hoàn chỉnh, nhưng: Symlink / Proc / <pid> / exe khác với các liên kết tượng trưng thông thường như thế nào?
muru

1
PATH = / usr / lib / klibc / bin: $ PATH sẽ đưa mèo và trở lại con đường của bạn
Joshua

@Joshua Và mỗi người trong số họ liên kết tĩnh! Đẹp!
muru

7

Bạn có thể tạm thời đặt các tệp từ đĩa CD trực tiếp hoặc hệ thống khác vào /binđể làm cho hệ thống của bạn có thể sử dụng được, sau đó thay thế chúng bằng các tệp từ cài đặt Ubuntu của bạn bằng cách chạy apt-get install --reinstallcác gói có nội dung /bin.


Đây là những gì tôi sẽ làm. DVD trực tiếp có cùng số phiên bản sẽ gần như giống nhau nếu không chính xác như cài đặt hiện tại. Nếu tôi có phiên bản đĩa hoặc USB Live, tôi có thể so sánh chúng và đăng câu trả lời như của bạn. Chủ đề này là một lý thuyết nhiều hơn nếu OP không bao giờ xóa / bin ở nơi đầu tiên, đó là một khả năng khi ông viết câu trả lời cùng lúc với câu hỏi trong tất cả khả năng. Vẫn còn thử nghiệm suy nghĩ rất tốt đẹp và phong cách viết tuyệt vời.
WinEunuuchs2Unix

Tôi khuyên bạn nên chỉnh sửa câu trả lời này để mở rộng nó với các chi tiết cụ thể về cách thực hiện việc này. (Xem thêm Làm thế nào để tôi viết một câu trả lời hay? Để có lời khuyên chung về loại câu trả lời nào được coi là có giá trị nhất trên AskUbfox.)
David Foerster

1

Một số bổ sung vào câu trả lời tuyệt vời này , sau khi tôi gặp phải vấn đề này (cùng với xóa /boot, /etc, /lib/lib64):

  • chrootđòi hỏi /lib/lib64phải có mặt; nếu không, bạn sẽ gặp phải lỗi sau:
    failed to run command ‘/bin/bash’: No such file or directory
    Tôi đã sao chép các lỗi này từ Hệ điều hành LiveCD và không gặp vấn đề gì khi khôi phục. YMMV tùy thuộc vào các gói bạn đã cài đặt trên hệ thống
  • Tôi không thể chỉnh sửa câu trả lời được tham chiếu ở trên, nhưng có một lỗi đánh máy:
    cp /etc/resolv.conf /mnt/etc/resolv.cof
    nên
    cp /etc/resolv.conf /mnt/etc/resolv.conf
  • /bootcó thể dễ dàng được khôi phục bằng cách sử dụng các công cụ grub. Xem tại đây .
  • Như câu trả lời này khuyến cáo, apt install --reinstall <package>là một cách tuyệt vời để khôi phục lại các file bị mất trong /bin, /lib/lib64.
    • Một số gói đòi hỏi cài đặt lại: libaio1, mysql-server, openvpn,vsftpd

Lưu ý đến bản thân:
rm -rf folder /*không giống nhưrm -rf folder/*

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.