Retirado accidentalmente / contenedor. ¿Cómo lo restauro?

91

Estaba trabajando en un directorio llamado bin. Después de que terminé, debido a la propiedad biny algunos archivos dentro de él, accidentalmente ejecuté:

sudo rm -r /bin

En lugar de:

sudo rm -r bin

Parece que mis manos solían agregar un /frente a todo lo que escribo.

¿Cómo puedo restaurar mi /bindirectorio?

Quiero los mismos archivos que pertenecen a mi Ubuntu, no me gusta copiarlos y pegarlos desde un disco en vivo u otro sistema en ejecución.

Ravexina
fuente
3
¿No es /binUbuntu solo un enlace simbólico en /usr/binestos días? ¿Entonces todo lo que necesita hacer es volver a colocar el enlace simbólico?
Muzer
3
@ Muzer Estoy ejecutando 16.04, y /binno es un enlace simbólico /usr/binaquí, creo que estaría en contra de la FHS. también si verificamos un paquete trivial como coreutilsen zesty (aquí) . podemos ver que se instalarán muchas cosas /binjunto con el /usr/bin, pero aún así puede ser un enlace, no estoy al tanto.
Ravexina
2
@Ravexina Arch Linux ya tiene enlaces simbólicos / bin a / usr / bin
Dmitry Kudriavtsev
1
Pensé que la gente se daría cuenta de que es una situación inventada, en realidad no eliminé mi /bin, consideré algo que podría pasarle a cualquiera (Basado en otra pregunta a la que respondí), luego escribí una instrucción para compartir mi conocimiento con otros :), aunque agradezco todos los comentarios, también son útiles para otras personas que vienen a leer esta pregunta. Gracias a todos;)
Ravexina
1
Me he acostumbrado a usar un comando "rm -r", o cualquier otro comando que pueda tener consecuencias significativas, escribo el comando y luego aparto las manos del teclado durante aproximadamente 3 segundos al menos antes de presionar ENTRAR. Eso me da la oportunidad de revisarlo y asegurarme de que tengo todo escrito correctamente y que sé lo que hará lo que planeo hacer. En raras ocasiones, durante esa pausa, decido que necesito borrar el comando, no siempre porque es el comando incorrecto, sino a veces porque primero necesito hacer alguna verificación.
ajb

Respuestas:

180

¿Es posible?

Bueno, la mayoría de las utilidades triviales e importantes están instaladas /bin, y ahora has perdido el acceso a todas ellas. De hecho, si reinicia, su sistema ya no podrá arrancar.

De todos modos, solucionaremos el problema y haremos que /binel contenido esté lo más cerca posible de donde estaba. La única diferencia sería algunos enlaces simbólicos que también arreglaremos.


¿Cómo?

Primero, debemos chrootentrar en su sistema roto, ¡pero con una pequeña diferencia ! Después de eso, obtendremos una lista de los paquetes instalados en su sistema que tienen cualquier archivo instalado en el /bindirectorio, luego solo descargaremos los paquetes necesarios y extraeremos los archivos necesarios /bin. Entonces habremos terminado.

Por ejemplo, después chroot, podemos obtener una lista de paquetes que tienen archivos instalados al /binusar:

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

Y también podemos usar:

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

para enumerar los archivos instalados por estos paquetes en /bin.

Luego, simplemente creamos una lista de todos los paquetes que son necesarios para nosotros, luego los descargamos y los extraemos /bincon algo como:

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

Sin embargo, debemos usar un script para verificar todos los paquetes instalados en nuestro sistema, porque hacerlo manualmente es una locura.

Entonces escribí un guión que hace todo lo que necesitamos. Encuentra todos los paquetes necesarios para que los restauremos /bin, nos muestra el nombre de cada paquete y sus archivos relacionados a los que pertenece /bin. Aquí hay una captura de pantalla:

Captura de pantalla de la lista de paquetes <code> / bin </code> como salida de mi script

Al final, elegimos reinstalar todos los paquetes o solo descargar y extraer los archivos necesarios para /bin(que es la opción recomendada):

Captura de pantalla de las opciones dadas por mi script

Puede obtener una copia de este script o descargarlo directamente .


Empecemos

chroot

Arranque su sistema con un disco en vivo que tenga la misma arquitectura que su Ubuntu instalado, abra una terminal y obtenga acceso de root:

sudo -i

Monta tu rootsistema de archivos (para mí es /dev/sda1):

mount /dev/sda1 /mnt

Necesitaremos conectividad a Internet, así que copie resolv.confdesde Ubuntu en vivo a su partición raíz montada:

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

Ahora copie el script en algún lugar de la partición montada, por ejemplo:

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

o puedes descargarlo usando wget, etc. como:

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

Monte otros caminos necesarios:

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

Y aquí está la pequeña diferencia : ¿cómo podemos acceder chroota un sistema dañado cuando no hay un /bindirectorio allí? ¿Qué shell debemos ejecutar?

Entonces cree un directorio bin temporal. Por ejemplo: nombrado bintmpdentro de la raíz del sistema roto:

mkdir /mnt/bintmp

Luego une la vida /bina eso:

mount --bind /bin /mnt/bintmp

Ingresa al sistema mientras configuras /bintmp/bashcomo tu shell de inicio de sesión:

chroot /mnt /bintmp/bash

Exporte /bintmpcomo su PATHvariable de entorno:

export PATH=/bintmp:$PATH

Dele al script el bit ejecutable:

chmod +x restore-bin.sh

Ejecute el script:

./restore-bin.sh

Espere a que se complete la búsqueda y luego responda la pregunta que vimos en la captura de pantalla. Comenzará a restaurar el /biny ya casi hemos terminado.

Una vez hecho esto, use CTRL+ Dpara salir del chrootentorno y desmontar las rutas montadas:

umount -R /mnt

Reinicia el sistema.

Restaurando los enlaces dentro /bin

Ahora casi todos los archivos dentro del /bindirectorio están de regreso, excepto alrededor de 5 enlaces simbólicos que son administrados por update-alternatives.

En su sistema en ejecución, ejecute:

sudo update-alternatives --all

Te hace algunas preguntas; simplemente puede presionar ENTERpara aceptarlos a todos.

Y ahora hemos terminado.

Ravexina
fuente
30
Esta es, sin duda, la mejor respuesta que he visto en Ask Ubuntu. Es extremadamente amable de su parte hacer tanto trabajo sabiendo que el OP se encuentra en una situación inconveniente.
Nonny Moose el
15
Oh espera tl; dr. Debería haberme dado cuenta de que hiciste eso.
Nonny Moose
Esto es increíble. Me encanta cómo el diseño de SE no da ninguna pista de que esta es una pregunta que se responde a sí misma.
Pedro A
55
@Hamsteriffic lo hace: vea el rectángulo que contiene el nombre del respondedor (firma): tiene un fondo más oscuro, que las publicaciones que no son del OP no. Esto se aplica a comentarios, respuestas y preguntas.
Ruslan
27

Si su sistema actual todavía tiene un shell en ejecución y acceso a Internet, esto se puede hacer utilizando herramientas existentes en otras partes del sistema. Supongo que solo borraste /bin. /binpor supuesto, tiene la utilidad más conveniente que podría usar en tal situación (busybox), pero sin eso, tendremos que ser un poco creativos.


Como ya tiene un shell en ejecución y ya sudoestá en funcionamiento /usr/bin, obtengamos un shell de root en ejecución antes de causar más daños. ¡Pero /bin/bashy la mayoría de los otros proyectiles se han ido! Afortunadamente, Linux todavía tiene una copia en memoria del shell que está utilizando. Entonces:

sudo /proc/$$/exe

Estrictamente hablando, no necesitamos un shell raíz para gran parte de lo que sigue. Pero de todos modos.

Ahora, dpkgtodavía funciona, al menos para encontrar qué paquetes tienen archivos /bin:

dpkg -S /bin

Podemos usarlo awkpara procesarlo y obtener los nombres de los paquetes, xargsy apt-getpara descargar los paquetes (todo incluido /usr/bin). Si tiene un directorio temporal que puede usar, cdallí, porque su directorio actual se volverá un poco desordenado:

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

Ahora, el mayor problema que tenemos es que /bin/tarfalta, y sin él, dpkgno se pueden extraer los archivos. Podemos llegar a dos tercios del camino, porque:

  1. .deblos archivos son en realidad ararchivos (nuevamente en /usr/bin):

    ar x tar_*.deb
    
  2. Consta de dos .tar.*archivos datay control:

    $ echo *.tar.*
    control.tar.gz data.tar.xz
    
  3. Mientras las utilidades gzip están en /bin, unxzestá en /usr/bin:

    unxz data.tar.xz
    

Ahora tenemos un data.tararchivo sin tarextraer tarde él.

Python al rescate ! Aquí es donde sudorealmente se necesita:

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

Ahora podemos usar dpkgpara extraer los archivos deb restantes para obtener un archivo razonablemente completo /bin:

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

Sin embargo, aún deberíamos hacer una instalación adecuada de los archivos deb, para que los enlaces simbólicos, etc., que serían creados por los paquetes se vuelvan a crear:

sudo apt install --reinstall ./*.deb

O:

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

Notas:

  1. No podemos usar Python 2 para extraer directamente el data.tar.xzarchivo, ya que Python 2 solo admite la compresión gzip y bzip2. Python 3, sin embargo, lo admite, por lo que puede usar Python 3 directamente sin unxz:

    sudo python3 -c 'import tarfile; tarfile.open("data.tar.xz").extractall("/")'
    
  2. Después de regresar /bin/tar, aún necesita extraer algunos de los archivos deb antes de poder usarlos apt-get: los shells, coreutils, etc. Es más fácil extraerlos todos y volver a instalarlos más tarde.
muru
fuente
No lo probé, pero casi lo leo por completo, fue increíble, en realidad traté de encontrar una copia de bash en la memoria, busqué un poco, no encontré nada interesante y después de ver que el alquitrán es no adentro /usr/bin, dije lo que sea que vaya con chroot ... Impresionante.
Ravexina
1
Una pregunta, ¿no es /proc/$$/exeun enlace /bin/bash? ¿Cómo funciona cuando /binse elimina? (Está funcionando, pero cómo), pensé que debería ser un enlace roto ... por eso dejé atrás esta Idea.
Ravexina
1
PATH = / usr / lib / klibc / bin: $ PATH pondrá a cat y sh en tu camino
Joshua
@Joshua ¡Y cada uno de ellos está estáticamente vinculado! ¡Agradable!
muru
7

Podrías poner temporalmente archivos de un CD en vivo u otro sistema en tu /binpara hacer que tu sistema sea utilizable, luego reemplazarlos con archivos de tu instalación de Ubuntu ejecutando apt-get install --reinstallpaquetes que contengan cosas /bin.

Dmitry Grigoryev
fuente
Esto es lo que haría. El DVD en vivo con el mismo número de versión será casi el mismo si no exactamente el mismo que el instalado actualmente. Si tuviera un disco o una versión USB Live, podría compararlos y publicar una respuesta como la suya. Este hilo es más una teoría si OP nunca eliminó / bin en primer lugar, lo cual es una posibilidad ya que escribió la respuesta al mismo tiempo que la pregunta con toda probabilidad. Todavía muy buen experimento mental y excelente estilo de escritura.
WinEunuuchs2Unix
Recomiendo editar esta respuesta para expandirla con detalles específicos sobre cómo hacer esto. (Consulte también ¿Cómo escribo una buena respuesta? Para obtener consejos generales sobre qué tipo de respuestas se consideran más valiosas en AskUbuntu.)
David Foerster
1

Algunas adiciones a este excelente respuesta , después de que me encontré con este tema (junto con el borrado /boot, /etc, /liby /lib64):

  • chrootrequiere /liby /lib64estar presente; de lo contrario, recibirá el siguiente error:
    failed to run command ‘/bin/bash’: No such file or directory
    Copié esto del sistema operativo LiveCD y no tuve ningún problema para restaurarlo. YMMV dependiendo de los paquetes que haya instalado en el sistema
  • No puedo editar la respuesta mencionada anteriormente, pero hay un error tipográfico:
    cp /etc/resolv.conf /mnt/etc/resolv.cof
    debería ser
    cp /etc/resolv.conf /mnt/etc/resolv.conf
  • /bootse puede restaurar fácilmente con herramientas grub. Ver aquí .
  • Como recomienda esta respuesta , apt install --reinstall <package>es una excelente manera de restaurar los archivos que faltan /bin, /liby /lib64.
    • Algunos paquetes que requieren reinstalación: libaio1, mysql-server, openvpn,vsftpd

Nota para uno mismo:
rm -rf folder /*no es lo mismo querm -rf folder/*

mrtumnus
fuente