web-dev-qa-db-fra.com

Supprimé accidentellement / bin. Comment puis-je le restaurer?

Je travaillais sur un répertoire nommé bin. Après avoir terminé, à cause de la propriété de bin et de certains fichiers qu'il contient, j'ai exécuté par erreur:

Sudo rm -r /bin

Au lieu de:

Sudo rm -r bin

Il semble que mes mains ajoutaient un / devant tout ce que je tape.

Comment puis-je restaurer mon répertoire /bin?

Je veux les mêmes fichiers qui appartiennent à mon Ubuntu, je n'aime pas les copier et les coller à partir d'un disque live ou d'un autre système en cours d'exécution.

90
Ravexina

C'est possible?

Eh bien, la plupart des utilitaires triviaux et importants sont installés dans /bin, et vous avez maintenant perdu l'accès à tous. En fait, si vous redémarrez, votre système ne pourra plus démarrer.

Quoi qu'il en soit, nous allons résoudre le problème et rendre le contenu de /bin aussi proche que possible de l'endroit où il se trouvait. La seule différence serait des liens symboliques que nous corrigerons également.


Comment?

Premièrement, nous devrions chrootdans votre système endommagé, mais avec une différence mineure ! Après cela, nous obtiendrons une liste des packages installés sur votre système contenant un fichier installé dans le répertoire /bin, puis nous ne téléchargerons que les packages nécessaires et nous extrairons les fichiers nécessaires dans /bin. Ensuite, nous aurons fini.

Par exemple, après chrootname__, nous pouvons obtenir la liste des paquets contenant des fichiers installés dans /bin en utilisant:

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

Et nous pouvons aussi utiliser:

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

pour lister les fichiers installés par ces paquets dans /bin.

Ensuite, nous créons simplement une liste de tous les paquets qui nous sont nécessaires, puis nous les téléchargeons et les extrayons vers /bin avec quelque chose comme:

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

Cependant, nous devons utiliser un script pour vérifier tous les packages installés sur notre système, car le faire manuellement est une folie.

J'ai donc écrit un script qui fait tout ce dont nous avons besoin. Il trouve tous les packages nécessaires à la restauration de /bin, nous indique le nom de chaque package et leurs fichiers associés appartenant à /bin. Voici une capture d'écran:

Screenshot of <code>/bin</code> package list as output by my script

À la fin, nous choisissons de réinstaller tous les packages ou seulement de télécharger et d'extraire les fichiers nécessaires dans /bin (l'option recommandée):

Screenshot of options given by my script

Vous pouvez récupérer ne copie de ce script ou le télécharger directement .


Commençons

chroot

Démarrez votre système avec un disque live ayant la même architecture que votre Ubuntu installé, ouvrez un terminal et obtenez un accès root:

Sudo -i

Montez votre système de fichiers root(pour moi, il s'agit de /dev/sda1):

mount /dev/sda1 /mnt

Nous aurons besoin de la connectivité à Internet, copiez donc resolv.conf de Ubuntu en direct sur votre partition racine montée:

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

Maintenant, copiez le script quelque part sur la partition montée, par exemple:

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

ou vous pouvez le télécharger en utilisant wgetname__, etc. comme:

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

Montez les autres chemins nécessaires:

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

Et voici la différence mineure : comment pouvons-nous chrootnom__ sur un système cassé alors qu'il n'y a pas de répertoire /bin dans celui-ci? Quel Shell devrions-nous courir?

Créez donc un répertoire bin temporaire. Par exemple: nommé bintmpdans la racine système cassée:

mkdir /mnt/bintmp

Liez ensuite le /bin en direct dans ceci:

mount --bind /bin /mnt/bintmp

Connectez-vous au système en définissant le /bintmp/bash comme shell de connexion:

chroot /mnt /bintmp/bash

Exportez le /bintmp en tant que votre variable d’environnement PATHname__:

export PATH=/bintmp:$PATH

Donnez au script le bit exécutable:

chmod +x restore-bin.sh

Exécutez le script:

./restore-bin.sh

Attendez que la recherche soit terminée, puis répondez à la question que nous avons vue dans la capture d'écran. Il va commencer à restaurer le /bin et nous avons presque terminé.

Une fois que c'est fait, utilisez CTRL+D pour sortir de chrootenvironment et démonter les chemins montés:

umount -R /mnt

Redémarrez le système.

Restauration des liens dans /bin

Maintenant, presque tous les fichiers du répertoire /bin sont de retour, sauf environ 5 liens symboliques gérés par update-alternatives.

Dans votre système en cours d'exécution, exécutez:

Sudo update-alternatives --all

Il te pose quelques questions; vous pouvez simplement appuyer sur ENTER les accepter tous.

Et maintenant nous avons fini.

179
Ravexina

Si votre système actuel dispose toujours d'un Shell et d'un accès Internet, vous pouvez le faire à l'aide d'outils existants ailleurs sur le système. Je suppose que vous n'avez supprimé que /bin. /bin a bien sûr l'utilitaire le plus pratique que vous puissiez utiliser dans une telle situation (busybox), mais sans cela, nous devrons faire preuve d'un peu de créativité.


Puisque vous avez déjà un shell en cours d'exécution et que Sudoest dans /usr/bin, obtenons nous-mêmes un shell racine en cours d'exécution avant de causer d'autres dommages. Mais /bin/bash et la plupart des autres obus ont disparu! Heureusement, Linux a toujours une copie en mémoire du shell que vous utilisez. Alors:

Sudo /proc/$$/exe

À proprement parler, nous n'avons pas besoin d'une racine Shell pour la majeure partie de ce qui suit. Mais peu importe.

Désormais, dpkgfonctionne toujours, du moins pour savoir quels packages contiennent des fichiers dans /bin:

dpkg -S /bin

Nous pouvons utiliser awkpour le traiter et obtenir les noms des packages, et xargset apt-get pour télécharger les packages (tous dans /usr/bin). Si vous avez un répertoire temporaire que vous pouvez utiliser, cdname__, car votre répertoire actuel va devenir un peu brouillon:

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

Maintenant, le plus gros problème que nous avons est que /bin/tar est manquant et sans cela, dpkgne peut pas extraire les archives. Nous pouvons obtenir les deux tiers du chemin, car:

  1. Les fichiers .deb sont en fait des archives ar(de nouveau dans /usr/bin):

    ar x tar_*.deb
    
  2. Composé de deux archives .tar.*, dataet controlname__:

    $ echo *.tar.*
    control.tar.gz data.tar.xz
    
  3. Alors que les utilitaires gzip sont dans /bin, unxzest dans /usr/bin:

    unxz data.tar.xz
    

Nous avons maintenant un fichier data.tar sans tarpour en extraire tarname__.

Python à la rescousse ! Voici où Sudoest vraiment nécessaire:

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

Maintenant nous pouvons utiliser dpkgpour extraire les fichiers deb restants afin d'obtenir un /bin raisonnablement complet:

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

Cependant, nous devons toujours faire une installation correcte des fichiers deb, afin que les liens symboliques, etc., créés par les paquetages soient recréés:

Sudo apt install --reinstall ./*.deb

Ou:

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

Remarques:

  1. Nous ne pouvons pas utiliser Python 2 pour extraire directement le fichier data.tar.xz, car Python 2 ne prend en charge que la compression gzip et bzip2. Python 3, cependant, le supporte, vous pouvez donc utiliser Python 3 directement sans unxzname__:

    Sudo python3 -c 'import tarfile; tarfile.open("data.tar.xz").extractall("/")'
    
  2. Après avoir récupéré /bin/tar, vous devez encore extraire certains des fichiers deb avant de pouvoir utiliser apt-get: les shells, coreutils, etc. Il est plus facile d'extraire tous les fichiers et de les réinstaller ultérieurement.
27
muru

Vous pouvez temporairement mettre les fichiers d'un live CD ou d'un autre système dans votre /bin pour rendre votre système utilisable, puis les remplacer par des fichiers de votre installation Ubuntu en exécutant apt-get install --reinstall pour les paquets contenant ce contenu dans /bin.

7
Dmitry Grigoryev

Quelques ajouts à cette excellente réponse , après avoir rencontré ce problème (avec la suppression de /boot, /etc, /lib et /lib64):

  • chrootrequiert /lib et /lib64 pour être présent; sinon vous obtiendrez l'erreur suivante:
    failed to run command ‘/bin/bash’: No such file or directory
    Je les ai copiées à partir du système d'exploitation LiveCD et je n'ai rencontré aucun problème de restauration. YMMV en fonction des packages que vous avez installés sur le système
  • Je ne peux pas éditer la réponse mentionnée ci-dessus, mais il y a une faute de frappe:
    cp /etc/resolv.conf /mnt/etc/resolv.cof
    devrait être
    cp /etc/resolv.conf /mnt/etc/resolv.conf
  • /boot peut facilement être restauré à l'aide des outils grub. Voir ici .
  • Comme cette réponse recommande, apt install --reinstall <package> est un excellent moyen de restaurer les fichiers manquants dans /bin, /lib et /lib64.
    • Certains packages nécessitant une réinstallation: libaio1, mysql-server, openvpnname__, vsftpdname__

Note pour moi-même:
rm -rf folder /* n'est pas la même chose que rm -rf folder/*

1
mrtumnus