Versehentlich entfernt / bin. Wie stelle ich es wieder her?

91

Ich habe an einem Verzeichnis mit dem Namen gearbeitet bin. Nachdem ich fertig war, binlief ich aufgrund des Eigentums und einiger darin enthaltener Dateien versehentlich:

sudo rm -r /bin

Anstatt von:

sudo rm -r bin

Es scheint, als hätten meine Hände vor allem, /was ich tippe, ein Zeichen eingefügt.

Wie kann ich mein /binVerzeichnis wiederherstellen ?

Ich möchte die gleichen Dateien, die zu meinem Ubuntu gehören. Ich möchte sie nicht von einer Live-Festplatte oder einem anderen laufenden System kopieren und einfügen.

Ravexina
quelle
3
Ist /binUbuntu nicht nur ein Symlink zu /usr/bindiesen Tagen? Alles was Sie tun müssen, ist den Symlink zurückzusetzen?
Muzer
3
@Muzer Ich lasse 16.04 laufen und /binist kein symbolischer Link zu /usr/binhier, ich denke das wäre gegen die FHS. auch wenn wir ein triviales Paket wie coreutilsin zesty (hier) überprüfen . Wir können sehen, dass eine Menge Dinge /binneben dem installiert werden /usr/bin, aber es kann trotzdem ein Link sein, dessen ich mir nicht bewusst bin.
Ravexina
2
@ Ravexina Arch Linux bereits symlinks / bin zu / usr / bin
Dmitry Kudriavtsev
1
Ich dachte, dass die Leute erkennen werden, dass es eine erfundene Situation ist, ich habe meine nicht entfernt /bin, ich habe überlegt, was jemand anderem passieren könnte (basierend auf einer anderen Frage, auf die ich geantwortet habe). Dann schrieb ich eine Anweisung, mein Wissen zu teilen mit anderen :), obwohl ich alle Kommentare schätze, sind sie auch für andere Leute hilfreich, die kommen, um diese Frage zu lesen. Vielen Dank an alle;)
Ravexina
1
Ich habe mir angewöhnt, jedes Mal, wenn ich einen "rm -r" -Befehl oder einen anderen Befehl verwende, der schwerwiegende Konsequenzen haben kann, den Befehl einzugeben und dann mindestens 3 Sekunden lang meine Hände von der Tastatur zu nehmen, bevor ich ihn drücke EINGEBEN. Das gibt mir die Möglichkeit, darüber nachzudenken und sicherzustellen, dass ich alles richtig eingetippt habe und weiß, was es tun wird, was ich vorhabe. In seltenen Fällen entscheide ich mich während dieser Pause, den Befehl zu löschen - nicht immer, weil es sich um den falschen Befehl handelt, sondern manchmal, weil ich zuerst eine Überprüfung durchführen muss.
Ajb

Antworten:

180

Ist es möglich?

Nun, die meisten einfachen und wichtigen Hilfsprogramme sind in installiert /bin, und jetzt haben Sie den Zugriff auf alle verloren. Tatsächlich kann Ihr System nach einem Neustart nicht mehr gestartet werden.

Wie auch immer, wir werden das Problem beheben und den /binInhalt so nah wie möglich an den Ort bringen, an dem er sich befand. Der einzige Unterschied wären einige symbolische Links, die wir ebenfalls reparieren werden.


Wie?

Zuerst sollten wir chrootin Ihr kaputtes System eindringen, aber mit einem kleinen Unterschied ! Danach erhalten wir eine Liste der auf Ihrem System installierten Pakete, auf denen eine Datei im /binVerzeichnis installiert ist. Anschließend laden wir nur die benötigten Pakete herunter und extrahieren die erforderlichen Dateien in dieses Verzeichnis /bin. Dann sind wir fertig.

Zum Beispiel können chrootwir nachher eine Liste von Paketen erhalten, die Dateien installiert haben, in /bindenen verwendet wird:

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

Und wir können auch verwenden:

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

um die installierten Dateien nach diesen Paketen aufzulisten /bin.

Dann erstellen wir einfach eine Liste aller Pakete, die für uns notwendig sind, laden sie herunter und extrahieren sie /binmit etwas wie:

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

Wir müssen jedoch ein Skript verwenden, um alle installierten Pakete auf unserem System zu überprüfen, da es nur Wahnsinn ist, dies manuell zu tun.

Also habe ich ein Skript geschrieben, das alles tut, was wir brauchen. Es findet alle für die Wiederherstellung erforderlichen Pakete /bin, zeigt den Namen jedes Pakets und die zugehörigen zugehörigen Dateien an /bin. Hier ist ein Screenshot:

Screenshot der Paketliste <code> / bin </ code>, die von meinem Skript ausgegeben wird

Am Ende entscheiden wir uns, alle Pakete neu zu installieren oder nur die erforderlichen Dateien herunterzuladen und zu extrahieren /bin(was die empfohlene Option ist):

Screenshot der von meinem Skript angegebenen Optionen

Sie können eine Kopie dieses Skripts herunterladen oder direkt herunterladen .


Lasst uns beginnen

Chroot

Booten Sie Ihr System mit einer Live-Festplatte, die dieselbe Architektur hat wie Ihr installiertes Ubuntu, öffnen Sie ein Terminal und erhalten Sie root-Zugriff:

sudo -i

Hängen Sie Ihr rootDateisystem ein (für mich ist es /dev/sda1):

mount /dev/sda1 /mnt

Wir benötigen eine Verbindung zum Internet, kopieren Sie also resolv.confvon Ubuntu live auf Ihre gemountete Root-Partition:

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

Kopieren Sie nun das Skript irgendwo auf die gemountete Partition, zB:

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

oder Sie können es herunterladen mit wget, etc. wie:

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

Andere notwendige Pfade einhängen:

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

Und hier ist der kleine Unterschied : Wie können wir chrootzu einem kaputten System kommen, wenn sich dort kein /binVerzeichnis befindet? Welche Shell sollen wir ausführen?

Erstellen Sie also ein temporäres bin-Verzeichnis. zB: benannt bintmpin Ihrem kaputten Systemstamm:

mkdir /mnt/bintmp

Dann binde das Leben /binin das:

mount --bind /bin /mnt/bintmp

Starten Sie das System, während Sie die /bintmp/bashals Login-Shell festlegen:

chroot /mnt /bintmp/bash

Exportieren Sie die /bintmpals PATHUmgebungsvariable:

export PATH=/bintmp:$PATH

Geben Sie dem Skript das ausführbare Bit:

chmod +x restore-bin.sh

Führen Sie das Skript aus:

./restore-bin.sh

Warten Sie, bis die Suche abgeschlossen ist, und beantworten Sie die im Screenshot angezeigte Frage. Es wird anfangen, das wiederherzustellen /binund wir sind fast fertig.

Verwenden Sie anschließend CTRL+ D, um die chrootUmgebung zu verlassen und die gemounteten Pfade zu entfernen:

umount -R /mnt

Starten Sie das System neu.

Wiederherstellung der Links innerhalb /bin

Jetzt sind fast alle Dateien im /binVerzeichnis zurück, mit Ausnahme von 5 symbolischen Links, die von verwaltet werden update-alternatives.

Führen Sie in Ihrem laufenden System Folgendes aus:

sudo update-alternatives --all

Es stellt Ihnen einige Fragen; Sie können einfach drücken ENTER, um alle zu akzeptieren.

Und jetzt sind wir fertig.

Ravexina
quelle
30
Dies ist ohne Zweifel die beste Antwort, die ich auf Ask Ubuntu gesehen habe. Es ist sehr nett von Ihnen, so viel Arbeit zu erledigen, wenn Sie wissen, dass sich das OP in einer ungünstigen Situation befindet.
Nonny Moose
15
Oh, warte, Dr. Ich hätte erkennen sollen, dass du das getan hast.
Nonny Moose
Das ist großartig. Ich finde es toll, dass SE-Design überhaupt keinen Hinweis darauf gibt, dass dies eine selbst beantwortete Frage ist.
Pedro A
5
@Hamsteriffic es macht: siehe das Rechteck mit dem Namen des Antwortenden (Unterschrift): es hat einen dunkleren Hintergrund, was die Beiträge nicht vom OP nicht tun. Dies gilt für Kommentare, Antworten und Fragen.
Ruslan
27

Wenn Ihr aktuelles System noch über eine laufende Shell und einen Internetzugang verfügt, können Sie hierfür Tools verwenden, die an anderer Stelle im System vorhanden sind. Ich gehe mal davon aus, dass du nur gelöscht hast /bin. /binNatürlich hat es das bequemste Dienstprogramm, das Sie in einer solchen Situation verwenden können (busybox), aber ohne das müssen wir ein wenig kreativ werden.


Da Sie bereits eine laufende Shell haben und sudosich in dieser befindet /usr/bin, lassen Sie uns eine laufende Root-Shell erstellen, bevor wir weiteren Schaden anrichten. Aber /bin/bashund die meisten anderen Muscheln sind weg! Glücklicherweise hat Linux immer noch eine speicherinterne Kopie der von Ihnen verwendeten Shell. Damit:

sudo /proc/$$/exe

Genau genommen brauchen wir für vieles, was folgt, keine Root-Shell. Aber wie auch immer.

Funktioniert jetzt dpkgimmer noch, zumindest um herauszufinden, in welchen Paketen Dateien enthalten sind /bin:

dpkg -S /bin

Wir können verwenden , awksie zu verarbeiten und die Paketnamen erhalten, und xargsund apt-getdie Pakete (alle in herunterladen /usr/bin). Wenn Sie ein temporäres Verzeichnis haben, das Sie dort verwenden können cd, weil Ihr aktuelles Verzeichnis etwas unordentlich wird:

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

Das größte Problem, das wir haben, ist, dass /bin/tares fehlt und ohne das wir dpkgdie Archive nicht extrahieren können. Wir können zwei Drittel des Weges dorthin schaffen, weil:

  1. .debDateien sind eigentlich arArchive (wieder in /usr/bin):

    ar x tar_*.deb
    
  2. Bestehend aus zwei .tar.*Archiven dataund control:

    $ echo *.tar.*
    control.tar.gz data.tar.xz
    
  3. Während die gzip-Dienstprogramme in sind /bin, unxzist in /usr/bin:

    unxz data.tar.xz
    

Jetzt haben wir eine data.tarDatei, ohne sie tarzu extrahieren tar.

Python zur Rettung ! Dies ist, wo sudowirklich benötigt wird:

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

Jetzt können wir verwenden dpkgeine einigermaßen vollständig erhalten die verbleibenden deb - Dateien zu extrahieren /bin:

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

Wir sollten jedoch trotzdem eine ordnungsgemäße Installation der deb-Dateien durchführen, damit Symlinks usw., die von Paketen erstellt werden, neu erstellt werden:

sudo apt install --reinstall ./*.deb

Oder:

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

Anmerkungen:

  1. Wir können Python 2 nicht verwenden, um die data.tar.xzDatei direkt zu extrahieren , da Python 2 nur die Komprimierung von gzip und bzip2 unterstützt. Python 3 unterstützt es jedoch, sodass Sie Python 3 direkt verwenden können, ohne unxz:

    sudo python3 -c 'import tarfile; tarfile.open("data.tar.xz").extractall("/")'
    
  2. Nach der Rückkehr /bin/tarmüssen Sie noch einige der deb-Dateien extrahieren, bevor Sie sie verwenden können apt-get: die Shells, Coreutils usw. Einfacher, alle zu extrahieren und später erneut zu installieren.
muru
quelle
Ich habe es nicht getestet, aber ich habe es fast vollständig gelesen, es war großartig, tatsächlich habe ich versucht, eine Kopie von bash im Gedächtnis zu finden, ich habe ein bisschen gesucht, ich habe nichts Interessantes gefunden und nachdem ich gesehen habe, dass Teer ist Nicht in /usr/bin, ich sagte, was auch immer ich mit Chroot gehe ... Super.
Ravexina
1
Eine Frage, kein /proc/$$/exeLink zu /bin/bash? Wie funktioniert es, wenn /bines entfernt wird? (Es funktioniert, aber wie), ich dachte, es sollte eine kaputte Verbindung sein ... deshalb habe ich diese Idee hinter mir gelassen.
Ravexina
3
@Ravexina erhielt keine vollständige Antwort, aber: Wie unterscheidet sich der / proc / <pid> / exe-Symlink von normalen Symlinks?
muru
1
PATH = / usr / lib / klibc / bin: $ PATH setzt cat und sh wieder in den Weg
Joshua
@Joshua Und jeder von ihnen statisch verlinkt! Nett!
muru
7

Sie können temporär Dateien von einer Live-CD oder einem anderen System in Ihr System /binlegen, um es nutzbar zu machen, und diese dann durch Dateien aus Ihrer Ubuntu-Installation ersetzen, indem Sie apt-get install --reinstallPakete ausführen, in denen sich Inhalte befinden /bin.

Dmitry Grigoryev
quelle
Das würde ich tun. Die Live-DVD mit der gleichen Versionsnummer ist fast gleich, wenn nicht genau dieselbe wie die aktuell installierte. Wenn ich eine Disc oder eine USB Live-Version hätte, könnte ich sie vergleichen und eine Antwort wie Ihre posten. Dieser Thread ist eher eine Theorie, wenn OP nie / bin an erster Stelle gelöscht hat, was eine Möglichkeit ist, da er die Antwort aller Wahrscheinlichkeit nach zur selben Zeit wie die Frage schrieb. Immer noch sehr schönes Gedankenexperiment und exzellenter Schreibstil.
WinEunuuchs2Unix
Ich empfehle , diese Antwort zu bearbeiten , um sie mit spezifischen Details zu erweitern. (Siehe auch Wie schreibe ich eine gute Antwort ?, um allgemeine Hinweise zu erhalten, welche Arten von Antworten auf AskUbuntu als am wertvollsten gelten.)
David Foerster,
1

Einige Ergänzungen dieser ausgezeichneten Antwort , nachdem ich dieses Problem aufgetreten (zusammen mit dem Löschen /boot, /etc, /libund /lib64):

  • chrootbenötigt /libund /lib64anwesend sein; Andernfalls erhalten Sie die folgende Fehlermeldung:
    failed to run command ‘/bin/bash’: No such file or directory
    Ich habe diese vom LiveCD-Betriebssystem kopiert und hatte keine Probleme beim Wiederherstellen. YMMV abhängig von den Paketen, die Sie auf dem System installiert haben
  • Ich kann die oben genannte Antwort nicht bearbeiten, aber es gibt einen Tippfehler:
    cp /etc/resolv.conf /mnt/etc/resolv.cof
    sollte sein
    cp /etc/resolv.conf /mnt/etc/resolv.conf
  • /bootkann leicht mit Madenwerkzeugen restauriert werden. Sehen Sie hier .
  • Da diese Antwort empfiehlt, apt install --reinstall <package>ist eine gute Möglichkeit , fehlende Dateien in wiederherzustellen /bin, /libund /lib64.
    • Einige Pakete , die Neu - Installation erforderlich: libaio1, mysql-server, openvpn,vsftpd

Hinweis für sich selbst:
rm -rf folder /*ist nicht dasselbe wierm -rf folder/*

mrtumnus
quelle