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


91

Je travaillais sur un répertoire nommé bin. Une fois que j'ai eu terminé, à cause de la propriété de binet de certains fichiers, j'ai accidentellement couru:

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 /binrépertoire?

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.


3
Sous /binUbuntu, n’est-ce pas simplement un lien symbolique vers /usr/binces jours-ci? Donc, tout ce que vous devez faire est de rétablir le lien symbolique?
Muzer

3
@Muzer je suis 16.04, et /binn'est pas un lien symbolique à /usr/binici, je pense que ce serait contre le FHS. aussi si nous vérifions un paquet trivial comme coreutilsdans zesty (ici) . nous pouvons voir que beaucoup de choses vont être installées à /bincôté du /usr/bin, mais ça peut quand même être un lien, je ne le sais pas.
Ravexina

2
@Ravexina Arch Linux déjà liens symboliques / bin vers / usr / bin
Dmitry Kudriavtsev

1
Je pensais que les gens se rendraient compte que c'était une situation inventée, je n'ai pas retiré mon message /bin, j'ai envisagé quelque chose qui pourrait arriver à quelqu'un d'autre (d'après une autre question à laquelle j'ai répondu), puis j'ai écrit une instruction pour partager mes connaissances avec les autres :), bien que j'apprécie tous les commentaires, ils sont également utiles aux autres personnes qui viennent lire cette question. Merci à tous;)
Ravexina

1
Je prends l'habitude de chaque fois que j'utilise une commande "rm -r", ou toute autre commande pouvant avoir des conséquences importantes, je tape la commande puis enlève mes mains du clavier pendant environ 3 secondes au moins avant de frapper ENTRER. Cela me donne l'occasion de l'examiner et de m'assurer que tout est bien dactylographié et que je sais ce qu'il fera ce que je compte faire. Dans de rares cas, pendant cette pause, je décide que je dois effacer la commande - pas toujours parce que c'est la mauvaise commande, mais parfois parce que je dois d'abord effectuer une vérification.
ajb

Réponses:


180

C'est possible?

Eh bien, la plupart des utilitaires les plus triviaux et les plus importants sont installés /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 /binle contenu aussi proche que possible de l'endroit où il se trouvait. La seule différence serait des liens symboliques que nous corrigerons également.


Comment?

Tout d’abord, nous devrions chrootintégrer votre système défectueux, mais avec une différence mineure ! Après cela, nous obtiendrons une liste des packages installés sur votre système contenant un fichier dans le /binrépertoire, puis nous ne téléchargerons que les packages nécessaires et en extrairons les fichiers nécessaires /bin. Ensuite, nous aurons fini.

Par exemple, après chroot, nous pouvons obtenir une liste des paquets qui ont des fichiers installés en /binutilisant:

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 packages nécessaires, puis nous les téléchargeons et les extrayons /binavec 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 à restaurer /bin, nous indique le nom de chaque package et les fichiers associés auxquels il appartient /bin. Voici une capture d'écran:

Capture d'écran de la liste de paquets <code> / bin </ code> en sortie de mon 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(ce qui est l'option recommandée):

Capture d'écran des options données par mon script

Vous pouvez récupérer une 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 rootsystème de fichiers (pour moi c'est /dev/sda1):

mount /dev/sda1 /mnt

Nous aurons besoin d'une connectivité à Internet, alors copiez resolv.confdepuis 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 wget, 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 chrootcréer un système défectueux alors qu’il n’ya pas de /binrépertoire dans ce répertoire? Quel shell devrions-nous exécuter?

Créez donc un répertoire bin temporaire. Exemple: nommé bintmpdans la racine de votre système endommagé:

mkdir /mnt/bintmp

Ensuite, liez le live /bindans ça:

mount --bind /bin /mnt/bintmp

Chroot dans le système en définissant le /bintmp/bashcomme shell de connexion:

chroot /mnt /bintmp/bash

Exportez la /bintmpcomme PATHvariable d’environnement:

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 /binet nous avons presque fini.

Ensuite, utilisez CTRL+ Dpour sortir de l’ chrootenvironnement et démonter les chemins montés:

umount -R /mnt

Redémarrez le système.

Restaurer les liens au sein /bin

Maintenant, presque tous les fichiers du /binrépertoire 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 ENTERpour les accepter tous.

Et maintenant nous avons fini.


30
C'est sans doute la meilleure réponse que j'ai vue sur Ask Ubuntu. C'est extrêmement gentil de votre part de travailler autant, sachant que le PO se trouve dans une situation peu pratique.
Nonny Moose

15
Oh, attends tl; dr. J'aurais dû me rendre compte que tu l'avais fait.
Nonny Moose

Ceci est incroyable. J'adore le fait que SE design ne laisse pas présager qu'il s'agit d'une question à réponse automatique.
Pedro A

5
@Hamsteriffic c'est le cas: voir le rectangle contenant le nom du répondeur (signature): il a un arrière-plan plus sombre, ce que ne font pas les publications non plus par le PO. Ceci s'applique aux commentaires, aux réponses et aux questions.
Ruslan

27

Si votre système actuel a toujours un shell et un accès Internet en cours d'exécution, vous pouvez le faire à l'aide d'outils existants ailleurs sur le système. Je suppose que vous avez seulement supprimé /bin. /binbien 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 depuis sudolors /usr/bin, obtenons-nous un shell racine en cours d’exécution avant d’endommager davantage. Mais /bin/bashet la plupart des autres coquilles 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’un shell root pour la majeure partie de ce qui suit. Mais peu importe.

Maintenant, dpkgfonctionne toujours, au moins pour trouver quels paquets ont des fichiers dans /bin:

dpkg -S /bin

Nous pouvons utiliser awkpour le traiter et obtenir les noms de paquets, et xargset apt-getpour télécharger les paquets (tous entrés /usr/bin). Si vous avez un répertoire temporaire que vous pouvez utiliser, cdlà - bas, 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 ayons, c'est qu'il /bin/tarmanque, et sans cela, dpkgnous ne pouvons pas extraire les archives. Nous pouvons obtenir les deux tiers du chemin, car:

  1. .debles fichiers sont en fait des ararchives (encore une fois dans /usr/bin):

    ar x tar_*.deb
    
  2. Constitué de deux .tar.*archives dataet control:

    $ echo *.tar.*
    control.tar.gz data.tar.xz
    
  3. Pendant que les utilitaires gzip sont dans /bin, unxzc'est dans /usr/bin:

    unxz data.tar.xz
    

Nous avons maintenant un data.tarfichier sans taren extraire tar.

Python à la rescousse ! C'est là sudoqu'il faut vraiment:

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

Nous pouvons maintenant utiliser dpkgpour extraire les fichiers deb restants pour obtenir un résultat raisonnablement complet /bin:

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 data.tar.xzfichier, car Python 2 ne prend en charge que la compression gzip et bzip2. Python 3, cependant, le supporte, vous pouvez donc utiliser directement Python 3 sans unxz:

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

Je ne l'ai pas testé, mais je l'ai presque lu complètement, c'était génial. En fait, j'ai essayé de trouver une copie de bash en mémoire, j'ai un peu cherché, je n'ai rien trouvé d'intéressant et après avoir vu que le goudron était pas dedans /usr/bin, j'ai dit tout ce que je vais avec chroot ... Génial.
Ravexina

1
Une question, n'est-ce pas /proc/$$/exeun lien /bin/bash? comment ça marche quand /binest enlevé? (Cela fonctionne, mais comment), j'ai pensé que ce devrait être un lien brisé ... c'est pourquoi j'ai abandonné cette idée.
Ravexina


1
PATH = / usr / lib / klibc / bin: $ PATH mettra le chat et le poisson sur votre chemin
Joshua

@ Josué Et chacun d'entre eux est lié statiquement! Agréable!
muru

7

Vous pouvez placer temporairement des fichiers d'un CD live ou d'un autre système dans votre ordinateur /binpour les rendre utilisables, puis les remplacer par des fichiers de votre installation Ubuntu en exécutant apt-get install --reinstalldes paquetages contenant des éléments /bin.


C'est ce que je ferais. Le DVD en direct ayant le même numéro de version sera presque le même sinon identique à celui actuellement installé. Si j'avais un disque ou une version USB Live, je pourrais les comparer et poster une réponse comme la vôtre. Ce fil est davantage une théorie si OP n’a jamais supprimé / bin, ce qui est une possibilité, car il a écrit la réponse en même temps que la question, selon toute vraisemblance. Encore très belle expérience de pensée et un excellent style d'écriture.
WinEunuuchs2Unix

Je recommande de modifier cette réponse pour la développer avec des détails spécifiques sur la façon de procéder. (Voir aussi Comment écrire une bonne réponse? Pour des conseils généraux sur les types de réponses considérés comme les plus utiles sur AskUbuntu.)
David Foerster

1

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

  • chrootexige /libet /lib64être présent; sinon, vous obtiendrez le message d'erreur suivant:
    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
  • /bootpeut facilement être restauré à l'aide des outils grub. Voir ici .
  • Comme le recommande cette réponse , apt install --reinstall <package>c’est un excellent moyen de restaurer les fichiers manquants /bin, /libet /lib64.
    • Certains paquets nécessaire en raison de : libaio1, mysql-server, openvpn,vsftpd

Note to self:
rm -rf folder /*n'est pas la même chose querm -rf folder/*

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.