Przypadkowo usunięty / bin. Jak mogę go przywrócić?

91

Pracowałem nad katalogiem o nazwie bin. Po skończeniu, z powodu własności bini niektórych plików, przypadkowo uruchomiłem:

sudo rm -r /bin

Zamiast:

sudo rm -r bin

Wygląda na to, że moje ręce dodawały /przed wszystkim, co piszę.

Jak mogę przywrócić mój /binkatalog?

Chcę tych samych plików, które należą do mojego Ubuntu, nie lubię kopiować i wklejać ich z dysku na żywo lub innego działającego systemu.

Ravexina
źródło
3
Czy /binna Ubuntu nie ma tylko dowiązania symbolicznego do /usr/bintych dni? Więc wszystko, co musisz zrobić, to odłożyć link symboliczny z powrotem?
Muzer 20.04.17
3
@Muzer Używam 16.04 i /binnie jest to symboliczny link do /usr/bintutaj, myślę, że byłoby to sprzeczne z FHS. także jeśli sprawdzimy trywialny pakiet jak coreutilsw zesty (tutaj) . możemy zobaczyć, że wiele rzeczy zostanie zainstalowanych /binobok /usr/bin, ale wciąż może to być link, nie jestem tego świadomy.
Ravexina,
2
@Ravexina Arch Linux już symlinks / bin do / usr / bin
Dmitry Kudriavtsev 20.04.17
1
Myślałem, że ludzie zdadzą sobie sprawę, że to wymyślona sytuacja, tak naprawdę nie usunąłem mojej /bin, rozważałem coś, co może się przydarzyć każdemu innemu (na podstawie innego pytania, na które odpowiedziałem), Potem napisałem instrukcję, aby podzielić się moją wiedzą z innymi :), choć doceniam wszystkie komentarze, są one również pomocne dla innych osób, które przychodzą przeczytać to pytanie. Dziękuję wszystkim;)
Ravexina
1
Przyzwyczaiłem się za każdym razem, gdy używam polecenia „rm -r” lub innego polecenia, które może mieć znaczące konsekwencje, wpisuję polecenie, a następnie odsuwam ręce od klawiatury na co najmniej 3 sekundy, zanim uderzę WCHODZIĆ. To daje mi szansę przejrzenia tego i upewnienia się, że wszystko wpisałem poprawnie i że wiem, co zrobi, co planuję zrobić. W rzadkich przypadkach podczas tej przerwy decyduję, że muszę usunąć polecenie - nie zawsze dlatego, że jest to niewłaściwe polecenie, ale czasem dlatego, że najpierw muszę wykonać weryfikację.
ajb

Odpowiedzi:

180

Czy to możliwe?

Cóż, większość trywialnych i ważnych narzędzi jest zainstalowanych /bin, a teraz straciłeś dostęp do wszystkich z nich. W rzeczywistości, jeśli zrestartujesz komputer, twój system nie będzie mógł się ponownie uruchomić.

W każdym razie zamierzamy naprawić problem i sprawić /bin, by zawartość była jak najbliżej miejsca, w którym się znajdowała. Jedyną różnicą byłyby niektóre dowiązania symboliczne, które również naprawimy.


W jaki sposób?

Po pierwsze, powinniśmy chrootwejść w twój zepsuty system, ale z niewielką różnicą ! Następnie otrzymamy listę zainstalowanych pakietów w twoim systemie, które mają dowolny zainstalowany plik w /binkatalogu, a następnie pobierzemy tylko potrzebne pakiety i wyodrębnimy niezbędne pliki /bin. Wtedy skończymy.

Na przykład później chrootmożemy uzyskać listę pakietów, które mają zainstalowane pliki przy /binużyciu:

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

I możemy również użyć:

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

aby wyświetlić listę zainstalowanych plików według tych pakietów w /bin.

Następnie po prostu tworzymy listę wszystkich pakietów, które są nam potrzebne, a następnie pobieramy je i rozpakowujemy za /binpomocą czegoś takiego:

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

Musimy jednak użyć skryptu, aby sprawdzić wszystkie zainstalowane pakiety w naszym systemie, ponieważ robienie tego ręcznie jest po prostu szaleństwem.

Napisałem więc skrypt, który robi wszystko, czego potrzebujemy. Znajduje wszystkie niezbędne pakiety do przywrócenia /bin, pokazuje nam nazwę każdego pakietu i powiązanych z nim plików, które należą /bin. Oto zrzut ekranu:

Zrzut ekranu z listą pakietów <code> / bin </code> jako wyjście mojego skryptu

Na koniec decydujemy się na ponowną instalację wszystkich pakietów lub pobranie i wyodrębnienie niezbędnych plików /bin(co jest zalecaną opcją):

Zrzut ekranu opcji podanych przez mój skrypt

Możesz pobrać kopię tego skryptu lub pobrać go bezpośrednio .


Zaczynajmy

chroot

Uruchom system z dysku na żywo, który ma taką samą architekturę jak zainstalowany Ubuntu, otwórz terminal i uzyskaj dostęp do roota:

sudo -i

Zamontuj swój rootsystem plików (dla mnie to /dev/sda1):

mount /dev/sda1 /mnt

Będziemy potrzebować łączności z Internetem, więc skopiuj resolv.confz Live Ubuntu na zamontowaną partycję root:

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

Teraz skopiuj skrypt gdzieś na zamontowanej partycji, np .:

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

lub możesz pobrać go za pomocą wgetitp., takich jak:

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

Zamontuj inne niezbędne ścieżki:

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

A oto drobna różnica : jak możemy chrootprzejść do uszkodzonego systemu, gdy nie ma /binw nim katalogu? Którą powłokę powinniśmy uruchomić?

Utwórz tymczasowy katalog bin. np .: nazwa bintmpw obrębie uszkodzonego katalogu głównego systemu:

mkdir /mnt/bintmp

Następnie połącz życie /binw to:

mount --bind /bin /mnt/bintmp

Chroot do systemu podczas ustawiania /bintmp/bashjako powłoki logowania:

chroot /mnt /bintmp/bash

Wyeksportuj /bintmpjako PATHzmienną środowiskową:

export PATH=/bintmp:$PATH

Podaj skryptowi plik wykonywalny:

chmod +x restore-bin.sh

Uruchom skrypt:

./restore-bin.sh

Poczekaj na zakończenie wyszukiwania, a następnie odpowiedz na pytanie, które widzieliśmy na zrzucie ekranu. Zacznie się przywracać /bini już prawie skończyliśmy.

Po zakończeniu użyj CTRL+, Daby wyjść ze chrootśrodowiska i odmontować zamontowane ścieżki:

umount -R /mnt

Uruchom ponownie system.

Przywracanie linków w ramach /bin

Teraz prawie wszystkie pliki w /binkatalogu są z powrotem, z wyjątkiem około 5 dowiązań symbolicznych, którymi zarządza update-alternatives.

W uruchomionym systemie uruchom:

sudo update-alternatives --all

Zadaje ci kilka pytań; możesz po prostu nacisnąć, ENTERaby zaakceptować je wszystkie.

A teraz skończymy.

Ravexina
źródło
30
To bez wątpienia najlepsza odpowiedź, jaką widziałem w Ask Ubuntu. Bardzo miło z twojej strony, że tak dużo pracy, wiedząc, że OP znajduje się w niewygodnej sytuacji.
Nonny Moose
15
Och, czekajcie; dr. Powinienem był zrozumieć, że to zrobiłeś.
Nonny Moose
To jest niesamowite. Uwielbiam to, że projekt SE nie daje żadnej wskazówki, że jest to pytanie, na które udzielono odpowiedzi.
Pedro A,
5
@Hamster jeśli to robi: zobacz prostokąt zawierający imię i nazwisko osoby odpowiadającej (podpis): ma ciemniejsze tło, czego nie robią posty nie napisane przez OP. Dotyczy to komentarzy, odpowiedzi i pytań.
Ruslan
27

Jeśli twój obecny system nadal ma działającą powłokę i dostęp do Internetu, można to zrobić za pomocą narzędzi istniejących gdzie indziej w systemie. Zakładam, że tylko usunąłeś /bin. /binoczywiście ma najwygodniejsze narzędzie, którego można użyć w takiej sytuacji (busybox), ale bez tego będziemy musieli się trochę kreatywnie.


Ponieważ masz już działającą powłokę, a ponieważ sudojest w /usr/binśrodku, zdobądźmy działającą powłokę root, zanim wyrządzimy dalsze szkody. Ale /bin/bashi większość innych pocisków zniknęła! Na szczęście Linux wciąż ma w pamięci kopię używanej powłoki. Więc:

sudo /proc/$$/exe

Ściśle mówiąc, nie potrzebujemy powłoki roota do większości następujących rzeczy. Ale w każdym razie.

Teraz dpkgnadal działa, przynajmniej do wyszukiwania pakietów, w których znajdują się pliki /bin:

dpkg -S /bin

Możemy użyć go awkdo przetworzenia go i uzyskania nazw pakietów xargsoraz apt-getdo pobrania pakietów (wszystko w /usr/bin). Jeśli masz katalog tymczasowy, którego możesz użyć cd, ponieważ w twoim bieżącym katalogu będzie trochę bałagan:

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

Teraz największym problemem jest to, że go /bin/tarbrakuje, a bez niego dpkgnie można wyodrębnić archiwów. Możemy tam dostać dwie trzecie, ponieważ:

  1. .debpliki są w rzeczywistości ararchiwami (ponownie w /usr/bin):

    ar x tar_*.deb
    
  2. Składa się z dwóch .tar.*archiwów datai control:

    $ echo *.tar.*
    control.tar.gz data.tar.xz
    
  3. Podczas gdy narzędzia gzip są włączone /bin, unxzznajduje się w /usr/bin:

    unxz data.tar.xz
    

Teraz mamy data.tarplik, z którego można go tarwyodrębnić tar.

Python na ratunek ! Oto, gdzie sudojest to naprawdę potrzebne:

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

Teraz możemy użyć dpkgdo wyodrębnienia pozostałych plików deb, aby uzyskać racjonalnie ukończone /bin:

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

Powinniśmy jednak nadal poprawnie instalować pliki deb, aby dowiązania symboliczne itp., Które byłyby tworzone przez pakiety, były ponownie tworzone:

sudo apt install --reinstall ./*.deb

Lub:

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

Uwagi:

  1. Nie możemy użyć Pythona 2 do bezpośredniego wyodrębnienia data.tar.xzpliku, ponieważ Python 2 obsługuje tylko kompresję gzip i bzip2. Jednak Python 3 obsługuje go, więc możesz używać Python 3 bezpośrednio bez unxz:

    sudo python3 -c 'import tarfile; tarfile.open("data.tar.xz").extractall("/")'
    
  2. Po powrocie /bin/tarnadal musisz wyodrębnić niektóre pliki deb, zanim będziesz mógł ich użyć apt-get: powłoki, coreutils itp. Łatwiej jest po prostu wyodrębnić je wszystkie i zainstalować ponownie później.
muru
źródło
Nie przetestowałem tego, ale prawie przeczytałem go całkowicie, było niesamowite, właściwie próbowałem znaleźć kopię bash w pamięci, trochę szukałem, nie znalazłem nic ciekawego i po tym, jak zobaczyłem, że smoła jest nie w /usr/bin, powiedziałem cokolwiek pójdę z chroot ... Niesamowite.
Ravexina
1
Pytanie, czy nie /proc/$$/exejest link do /bin/bash? jak to działa po /binusunięciu? (Działa, ale jak), pomyślałem, że powinien to być zepsuty link ... dlatego zostawiłem ten pomysł za sobą.
Ravexina
1
ŚCIEŻKA = / usr / lib / klibc / bin: $ ŚCIEŻKA ponownie umieści kota i sh na twojej drodze
Joshua
@Joshua I każdy z nich jest statycznie powiązany! Miły!
mur
7

Możesz tymczasowo umieścić pliki z płyty CD na żywo lub innego systemu w swoim /binsystemie, aby system był użyteczny, a następnie zastąpić je plikami z instalacji Ubuntu, uruchamiając apt-get install --reinstallpakiety, które mają coś w sobie /bin.

Dmitrij Grigoriew
źródło
Tak bym zrobił. Live DVD będący tym samym numerem wersji będzie prawie taki sam, jeśli nie dokładnie taki sam, jak aktualnie zainstalowany. Gdybym miał płytę lub wersję USB Live, mógłbym je porównać i opublikować odpowiedź taką jak Twoja. Wątek ten jest bardziej teorią, jeśli OP nigdy nie został usunięty / bin, co jest możliwe, ponieważ napisał odpowiedź w tym samym czasie, co pytanie z dużym prawdopodobieństwem. Wciąż bardzo miły eksperyment myślowy i doskonały styl pisania.
WinEunuuchs2Unix
Zalecam edycję tej odpowiedzi, aby rozszerzyć ją o szczegółowe informacje na temat tego, jak to zrobić. (Zobacz także Jak napisać dobrą odpowiedź? Zawiera ogólne porady na temat tego, jakie rodzaje odpowiedzi są uważane za najcenniejsze na AskUbuntu.)
David Foerster
1

Niektóre dodatki do tego doskonałą odpowiedź , po I napotkał ten problem (wraz z usunięciem /boot, /etc, /libi /lib64):

  • chrootwymaga /libi /lib64musi być obecny; w przeciwnym razie pojawi się następujący błąd:
    failed to run command ‘/bin/bash’: No such file or directory
    Skopiowałem je z LiveCD OS i nie miałem problemów z przywróceniem. YMMV w zależności od pakietów zainstalowanych w systemie
  • Nie mogę edytować odpowiedzi, o której mowa powyżej, ale jest literówka:
    cp /etc/resolv.conf /mnt/etc/resolv.cof
    powinna być
    cp /etc/resolv.conf /mnt/etc/resolv.conf
  • /bootmożna go łatwo przywrócić za pomocą narzędzi grub. Zobacz tutaj .
  • Jak ta odpowiedź zaleca, apt install --reinstall <package>jest to świetny sposób, aby przywrócić brakujące pliki /bin, /liba /lib64.
    • Niektóre pakiety, które wymagały ponownej instalacji: libaio1, mysql-server, openvpn,vsftpd

Uwaga do siebie:
rm -rf folder /*to nie to samo corm -rf folder/*

mrtumnus
źródło