J'ai supprimé / bin / rm. Comment puis-je le récupérer?

168

Juste pour le fun, je pensais utiliser cette commande sur mon Raspberry Pi sous Raspbian:

sudo rm -f /bin/rm

Je pensais pouvoir réinstaller simplement coreutils: j'avais tort!

apt-get install --reinstall coreutilsdonne une erreur de dpkg, en disant qu'il ne pouvait pas supprimer le paquet. Compiler à partir des sources ne fonctionne pas car les Makefileutilisations rm.

Comment puis-je obtenir un rmretour en arrière?

utilisateur60684
la source
9
Chaque fichier .deb est en principe une archive que vous pouvez décompresser et simplement copier l’exécutable rm dans / bin.
Schaiba
1
Quel OS est-ce? Linux? Unix? Autre chose? Si Linux, quelle distribution? 64 bits? 32?
terdon
12
ln -s /usr/lib/initramfs-tools/bin/busybox /bin/rm(ou /bin/busybox, ou l'extraire d'un initrd)
Stéphane Chazelas le
10
Le Raspberry Pi a son système d’exploitation sur une carte mémoire SD. Vous pouvez donc extraire le fichier binaire rm du package sur un autre ordinateur et le copier à nouveau sur la carte. En tout cas, cascade hilarante que vous avez tirée là-bas et très audacieux de l'admettre publiquement :)
Christian
15
@ user645715 37 personnes ont trouvé cette question amusante.
Brilliand

Réponses:

194
sudo touch /bin/rm && sudo chmod +x /bin/rm
apt-get download coreutils
sudo dpkg --unpack coreutils*

Et plus jamais.


Pourquoi n'avez-vous pas utilisé sudo avec apt-get?

Parce que la downloadcommande n'en a pas besoin:

download
download téléchargera le paquet binaire donné dans le répertoire courant.

Donc, à moins que vous ne soyez dans un répertoire que vous ne pouvez pas écrire, vous n'avez pas besoin de l'utiliser sudo, et cela pourrait poser problème plus tard, car vous aurez besoin d' rootautorisations pour supprimer / déplacer le paquet.

Braiam
la source
3
apt-get doit être exécuté avec sudo :)
AWippler
31
@AWippler Non, dans ce cas, non.
Braiam
5
Notez qu'un fichier exécutable vide est exécuté en tant que script shell qui ne fait rien. Donc, cela signifie invoquer /bin/sh. Il aurait été plus simple de faire un sudo ln -s true /bin/rmou même mieux sudo ln -s busybox /bin/rmd'avoir un travail rm.
Stéphane Chazelas
1
apt-getVous n'avez pas besoin de sudo si vous n'avez pas téléchargé coreutils, sinon, il ne pourra pas écrire dans /varlequel Debian enregistre les fichiers téléchargés.
Kristopher Ives
3
@KristopherIves mal ... apt-gettélécharge le package dans le répertoire courant toujours (oui, même si vous avez utilisé sudo), sauf si vous êtes dans un répertoire que vous ne pouvez pas écrire tant qu'utilisateur vous n'avez pas besoin sudo. Veuillez vérifier les pages de manuel.
Braiam
106

debianet ses dérivés (et probablement la plupart des autres distributions) viennent avec busyboxce qui est utilisé dans le initramfs.

busybox regroupe la plupart des utilitaires de ligne de commande essentiels dans un seul exécutable.

Vous pouvez temporairement créer un lien symbolique /bin/rmvers /bin/busybox:

ln -s busybox /bin/rm

Pour obtenir un travail rm(après quoi vous pouvez faire votre apt-get install --reinstall coreutils).

Cette même méthode peut être utilisée pour tous les autres utilitaires busyboxinclus. Cette liste varie d'un déploiement à l'autre. Vous pouvez obtenir la liste avec busybox --list.

Notez cependant qu'il s'agit de versions limitées des utilitaires correspondants. Ils supportent parfois les extensions GNU, mais généralement pas et certains d’entre eux ne supporteront même pas toutes les fonctionnalités standard / POSIX (certaines fonctionnalités peuvent être activées / désactivées lors de la compilation).

Alternativement, vous pouvez utiliser zshla fonction intégrée:

#! /bin/zsh
zmodload zsh/files
rm "$@"

Le zsh/filesmodule fournit avec quelques commandes internes supplémentaires ( rm, mv, ln, mkdir, rmdir, chown, chmod, sync). C'est utile dans ce genre de situation ou lorsque vous ne pouvez pas créer plus de processus mais que vous avez un zshfonctionnement interactif .

ksh93a aussi un certain nombre de commandes supplémentaires / option buitin, mais pas rmparmi eux ( basename, chmod, dirname, getconf, head, mkdir, logname, cat, cmp, cut, uname, wc, sync). Vous pouvez les invoquer avec:

command /opt/ast/bin/the-command

dans un ksh93script.

Stéphane Chazelas
la source
5
Très bonne réponse. Je me demande si le PO a vraiment besoin de réinstaller le réel rm. ;-)
joeytwiddle
En effet. En fait, cela me fait penser aussi à la suppression de coreutils ... :-)
Damon
4
@ Damon: coreutils fournit une version étendue des commandes de base par rapport à busybox. Ainsi, bien que busybox puisse suffire à répondre aux exigences de SUSv3, coreutils offre davantage de fonctionnalités. par exemple, busybox a un support limité d'i18n.
Liori
2
@ Liori: Je plaisantais à moitié, bien qu'il y a 10-15 ans, je l'aurais probablement fait dans cette situation (les "fonctionnalités" ajoutées, en particulier i18n , ne sont pas un avantage à mon avis - des traductions inintelligibles, et apprendre à utiliser des commutateurs qui interrompent les scripts de manière inattendue sur un autre ordinateur (non, merci). Cependant, de nos jours, je suis heureux si seul un système Linux fonctionne correctement tel qu’installé sans que je ne touche à rien et sans avoir à déplacer / supprimer / éditer des fichiers système / config ou des fichiers binaires. Ce qui malheureusement n'est toujours pas assez souvent le cas, alors je ne touche sûrement pas à quelque chose qui fonctionne :-)
Damon
28

Dans le cas apt-getou les dpkgbesoins rmet sans rmréinstallation n'est pas posssible, vous pouvez émuler rmavec perl:

cat > /bin/rm << "EOF"
#!/usr/bin/perl
foreach (@ARGV) { unlink $_ or warn "$@:$!"; }
EOF
chmod +x /bin/rm
NlightNFotis
la source
3
Notez qu'il ne gère pas -ret que le fait de ne pas renvoyer un état de sortie correct peut poser problème.
Stéphane Chazelas
6
@ StephaneChazelas, il suffit de permettre apt-get install --reinstall coreutilsà l'OP de revenir à la normale.
terdon
c'est pourquoi j'ai écrit "au cas où". le paquet coreutils n'a pas de script. généralement, les scripts de pré-installation et de post-installation échouent en cas d'erreur si les fichiers existent ou n'existent pas, par exemple s'ils doivent être supprimés. Et oui, c’est vrai que j’étais trop paresseux pour vérifier le colis à l’avance.
vous pouvez aussi émuler rmavec mv(à 'poubelle')
sendmoreinfo
14

Je voudrais essayer d'obtenir le bon rmbinaire à partir d'une autre machine, puis en utilisant scpou quelque chose pour le copier sur le Pi. Cela ne fonctionne bien sûr que si scpest déjà installé ...

Si scpn'est pas disponible, alors nc(alias netcat) du côté de l'envoi et bash avec une /dev/tcp/HOST/PORTredirection du côté de la réception pourraient également fonctionner.

Si vous n'avez pas d'autre machine Raspbian, vous pouvez récupérer le paquet coreutils (obtenir la .debversion correcte) et le décompresser avec dpkg-deb(sur Debian / Ubuntu / Mint /…, même si ce n'est pas sur un Pi):

dpkg-deb --fsys-tarfile coreutils*.deb | tar xf - ./bin/rm

Si vous n'avez pas d'autre machine avec dpkg, vous pouvez extraire le fichier avec ar(depuis les outils de développement de binutils) et tar:

ar p coreutils*.deb data.tar.gz  | tar xzf - ./bin/rm
MathematicalOrchid
la source
8
Si scpn'est pas disponible, alors nc(aka netcat) du côté de l'envoi et bashavec une /dev/tcp/HOST/PORTredirection du côté de la réception pourrait également fonctionner.
MvG
13

Comme il s'agit de Debian (ou Ubuntu), il existe un moyen simple de récupérer les fichiers:

mkdir /tmp/coreutils
sudo dpkg-deb --extract /var/cache/apt/archives/coreutils_ [tab complete for correct version].deb /tmp/coreutils
sudo cp /tmp/coreutils/bin/rm /bin

Cela fonctionne parce qu'apt-get a téléchargé coreutils.deb avant d'essayer de l'installer et que dpkg-deb a la garantie d'exister sur un système basé sur Debian.

Ne pas extraire directement dans / tmp, cela modifie les autorisations sur le répertoire parent.

Si vous voulez jouer, vous voudrez peut-être installer le paquet busybox-static, qui fonctionnera même si vous cassez tout le reste.

Dan Merillat
la source