Removido acidentalmente / compartimento. Como faço para restaurá-lo?


91

Eu estava trabalhando em um diretório chamado bin. Depois que terminei, por causa da propriedade bine de alguns arquivos nele, executei acidentalmente:

sudo rm -r /bin

Ao invés de:

sudo rm -r bin

Parece que minhas mãos adicionavam um /na frente de tudo que eu digito.

Como posso restaurar meu /bindiretório?

Quero os mesmos arquivos que pertencem ao meu Ubuntu, não gosto de copiá-los e colá-los de um disco ativo ou de outro sistema em execução.


3
O /binUbuntu não é apenas um link simbólico /usr/binatualmente? Então, tudo o que você precisa fazer é colocar o link simbólico de volta?
Muzer #

3
@ Muuzer Estou executando o 16.04, e /binnão é um link simbólico /usr/binaqui, acho que seria contra o FHS. também se verificarmos um pacote trivial como coreutilsem zesty (aqui) . podemos ver que muitas coisas serão instaladas /binao lado do /usr/bin, mas ainda assim pode ser um link, não sei.
Ravexina

2
@Ravexina Arch Linux já symlinks / bin para / usr / bin
Dmitry Kudriavtsev

1
Eu pensei que as pessoas perceberiam que é uma situação inventada, eu realmente não removi a minha /bin, considerei algo que poderia acontecer com qualquer outra pessoa (com base em outra pergunta à qual respondi), então escrevi uma instrução para compartilhar meu conhecimento com outras pessoas :), embora eu aprecie todos os comentários, eles também são úteis para outras pessoas que vêm ler esta pergunta. Obrigado a todos;)
Ravexina

1
Adquiri o hábito de sempre que uso um comando "rm -r" ou qualquer outro comando que possa ter consequências significativas. Digito o comando e, em seguida, afasto minhas mãos do teclado por cerca de 3 segundos antes de pressionar ENTRAR. Isso me dá a chance de analisar e garantir que tudo esteja digitado corretamente e que eu sei o que fará o que planejo fazer. Em raras ocasiões, durante essa pausa, decido que preciso apagar o comando - nem sempre porque é o comando errado, mas às vezes porque preciso fazer alguma verificação primeiro.
ajb

Respostas:


180

É possível?

Bem, os utilitários mais triviais e importantes estão instalados /bine agora você perdeu o acesso a todos eles. De fato, se você reiniciar, seu sistema não poderá mais inicializar.

De qualquer forma, vamos corrigir o problema e tornar /bino conteúdo o mais próximo possível de onde estava. A única diferença seria alguns links simbólicos que também serão corrigidos.


Quão?

Primeiro, devemos chrootentrar no seu sistema danificado, mas com uma pequena diferença ! Depois disso, obteremos uma lista de pacotes instalados no seu sistema que possuem qualquer arquivo instalado no /bindiretório, então vamos baixar apenas os pacotes necessários e extrair os arquivos necessários /bin. Então estaremos prontos.

Por exemplo, depois chroot, podemos obter uma lista de pacotes que instalaram arquivos /binusando:

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

E também podemos usar:

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

para listar os arquivos instalados por esses pacotes no /bin.

Em seguida, simplesmente criamos uma lista de todos os pacotes necessários para nós, depois baixamos e extraímos para /binalgo como:

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

No entanto, devemos usar um script para verificar todos os pacotes instalados em nosso sistema, porque fazê-lo manualmente é apenas loucura.

Então, eu escrevi um script que faz tudo o que precisamos. Ele encontra todos os pacotes necessários para restauração /bin, mostra o nome de cada pacote e seus arquivos relacionados aos quais pertence /bin. Aqui está uma captura de tela:

Captura de tela da lista de pacotes <code> / bin </code> como resultado do meu script

No final, optamos por reinstalar todos os pacotes ou apenas baixar e extrair os arquivos necessários para /bin(que é a opção recomendada):

Captura de tela das opções fornecidas pelo meu script

Você pode pegar uma cópia desse script ou fazer o download diretamente .


Vamos começar

chroot

Inicialize seu sistema com um disco ativo com a mesma arquitetura do Ubuntu instalado, abra um terminal e obtenha acesso root:

sudo -i

Monte seu rootsistema de arquivos (para mim é /dev/sda1):

mount /dev/sda1 /mnt

Precisamos de conectividade com a Internet, então copie resolv.confdo Ubuntu ao vivo para sua partição raiz montada:

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

Agora copie o script para algum lugar da partição montada, por exemplo:

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

ou você pode baixá-lo usando wgetetc., como:

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

Monte outros caminhos necessários:

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

E aqui está a pequena diferença : como podemos entrar chrootem um sistema danificado quando não há /bindiretório lá? Qual shell devemos executar?

Portanto, crie um diretório bin temporário. por exemplo: nomeado bintmpdentro da raiz do sistema corrompida:

mkdir /mnt/bintmp

Em seguida, vincule a vida /bina isso:

mount --bind /bin /mnt/bintmp

Faça chroot no sistema enquanto define o /bintmp/bashcomo seu shell de login:

chroot /mnt /bintmp/bash

Exporte a variável de ambiente /bintmpcomo PATH:

export PATH=/bintmp:$PATH

Dê ao script o bit executável:

chmod +x restore-bin.sh

Execute o script:

./restore-bin.sh

Aguarde a pesquisa ser concluída e responda à pergunta que vimos na captura de tela. Ele começará a restaurar o /bine estamos quase terminando.

Depois de concluído, use CTRL+ Dpara sair do chrootambiente e desmontar os caminhos montados:

umount -R /mnt

Reinicie o sistema.

Restaurando os Links dentro /bin

Agora quase todos os arquivos no /bindiretório estão de volta, exceto cerca de 5 links simbólicos que são gerenciados por update-alternatives.

No seu sistema em execução, execute:

sudo update-alternatives --all

Ele faz algumas perguntas; você pode simplesmente pressionar ENTERpara aceitar todos eles.

E agora terminamos.


30
Esta é, sem dúvida, a melhor resposta que eu já vi no Ask Ubuntu. É extremamente gentil da sua parte trabalhar tanto sabendo que o OP está em uma situação inconveniente.
precisa

15
Oh espere tl; dr. Eu deveria ter percebido que você fez isso.
quer

Isso é incrível. Eu amo como o design de SE não dá nenhuma dica de que essa é uma pergunta auto-respondida.
Pedro A

5
@ Hamsteriffic: veja o retângulo que contém o nome do atendedor (assinatura): ele tem um fundo mais escuro, que as postagens não do OP não possuem. Isso se aplica a comentários, respostas e perguntas.
Ruslan #

27

Se o seu sistema atual ainda tiver um shell em execução e acesso à Internet, isso poderá ser feito usando as ferramentas existentes em outras partes do sistema. Eu estou supondo que você apenas excluiu /bin. /biné claro que possui o utilitário mais conveniente que você poderia usar em uma situação dessas (busybox), mas sem isso, teremos que ser um pouco criativos.


Como você já possui um shell em execução e já sudoestá dentro /usr/bin, vamos obter um shell raiz em execução antes de causar mais danos. Mas /bin/bashe a maioria das outras conchas se foram! Felizmente, o Linux ainda tem uma cópia na memória do shell que você está usando. Assim:

sudo /proc/$$/exe

A rigor, não precisamos de um shell raiz para muito do que se segue. Mas mesmo assim.

Agora, dpkgainda funciona, pelo menos para descobrir quais pacotes têm arquivos /bin:

dpkg -S /bin

Podemos usá awk-lo para processá-lo, obter os nomes dos pacotes xargse apt-getfazer o download dos pacotes (all in /usr/bin). Se você tiver um diretório temporário que possa ser usado cd, porque o diretório atual ficará um pouco confuso:

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

Agora, o maior problema que temos é que /bin/tarestá faltando e sem ele não é dpkgpossível extrair os arquivos. Podemos obter dois terços do caminho até lá, porque:

  1. .debos arquivos são realmente ararquivos (novamente em /usr/bin):

    ar x tar_*.deb
    
  2. Composto por dois .tar.*arquivos datae control:

    $ echo *.tar.*
    control.tar.gz data.tar.xz
    
  3. Enquanto os utilitários gzip estão /bin, unxzestá em /usr/bin:

    unxz data.tar.xz
    

Agora temos um data.tararquivo sem tarextraí tar-lo.

Python para o resgate ! É aqui que sudoé realmente necessário:

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

Agora podemos usar dpkgpara extrair os arquivos deb restantes para obter uma conclusão razoavelmente completa /bin:

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

No entanto, ainda devemos fazer uma instalação adequada dos arquivos deb, para que os links simbólicos etc. que seriam criados pelos pacotes sejam recriados:

sudo apt install --reinstall ./*.deb

Ou:

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

Notas:

  1. Não podemos usar o Python 2 para extrair diretamente o data.tar.xzarquivo, pois o Python 2 suporta apenas a compressão gzip e bzip2. O Python 3, no entanto, suporta, então você pode usar o Python 3 diretamente sem unxz:

    sudo python3 -c 'import tarfile; tarfile.open("data.tar.xz").extractall("/")'
    
  2. Depois de voltar /bin/tar, você ainda precisa extrair alguns dos arquivos deb antes de poder usá-los apt-get: shells, coreutils, etc. Mais fácil extrair todos eles e reinstalar mais tarde.

Não testei, mas quase li completamente, foi incrível, na verdade, tentei encontrar uma cópia do bash na memória, procurei um pouco, não encontrei nada interessante e depois que vi que o alcatrão está não /usr/bin, eu disse o que quer que eu vá com chroot ... Incrível.
Ravexina 19/04

1
Uma pergunta, não é /proc/$$/exeum link para /bin/bash? como funciona quando /biné removido? (Está funcionando, mas como), pensei que deveria ser um link quebrado ... foi por isso que deixei essa idéia para trás.
Ravexina

3

1
PATH = / usr / lib / klibc / bin: $ PATH irá colocar gato e sh volta em seu caminho
Joshua

@ Josué E todos eles vinculados estaticamente! Agradável!
Muni

7

Você pode colocar temporariamente arquivos de um CD ao vivo ou outro sistema no seu /binpara tornar seu sistema utilizável e substituí-los por arquivos da instalação do Ubuntu executando apt-get install --reinstallpacotes que contenham /bin.


Isto é o que eu faria. O DVD ao vivo com o mesmo número de versão será quase o mesmo, se não exatamente o mesmo que o atual instalado. Se eu tivesse um disco ou uma versão do USB Live, poderia compará-los e postar uma resposta como a sua. Esse tópico é mais uma teoria se o OP nunca excluiu / bin em primeiro lugar, o que é uma possibilidade, pois ele escreveu a resposta ao mesmo tempo que a pergunta com toda a probabilidade. Experiência de pensamento ainda muito agradável e excelente estilo de escrita.
WinEunuuchs2Unix

Eu recomendo editar esta resposta para expandi-la com detalhes específicos sobre como fazer isso. (Veja também Como faço para escrever uma boa resposta? Para o conselho geral sobre que tipos de respostas são consideradas mais valiosas sobre AskUbuntu.)
David Foerster

1

Algumas adições a este excelente resposta , depois eu encontrei esta questão (juntamente com exclusão /boot, /etc, /libe /lib64):

  • chrootrequer /libe /lib64estar presente; caso contrário, você receberá o seguinte erro:
    failed to run command ‘/bin/bash’: No such file or directory
    Eu os copiei do LiveCD OS e não tive problemas para restaurar. YMMV, dependendo dos pacotes que você instalou no sistema
  • Não consigo editar a resposta mencionada acima, mas há um erro de digitação:
    cp /etc/resolv.conf /mnt/etc/resolv.cof
    deve ser
    cp /etc/resolv.conf /mnt/etc/resolv.conf
  • /bootpode ser facilmente restaurado usando ferramentas grub. Veja aqui .
  • Como essa resposta recomenda, apt install --reinstall <package>é uma ótima maneira de restaurar arquivos ausentes no Windows /bin, /libe /lib64.
    • Alguns pacotes que exigiam a reinstalação: libaio1, mysql-server, openvpn,vsftpd

Nota para si mesmo:
rm -rf folder /*não é o mesmo querm -rf folder/*

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.