Случайно удален / bin. Как мне его восстановить?

91

Я работал над каталогом с именем bin. После того, как я закончил, из-за владения binи некоторых файлов в нем я случайно запустил:

sudo rm -r /bin

Вместо:

sudo rm -r bin

Кажется, мои руки добавляли /перед всем, что я печатаю.

Как я могу восстановить мой /binкаталог?

Мне нужны те же файлы, которые принадлежат моему Ubuntu, я не люблю копировать и вставлять их с живого диска или другой работающей системы.

Ravexina
источник
3
Разве /binв Ubuntu не просто символическая ссылка на /usr/binэти дни? Так что все, что вам нужно сделать, это вернуть символическую ссылку обратно?
Музер
3
@Muzer У меня работает 16.04, и /binэто не символическая ссылка /usr/bin, думаю, это будет против FHS. Также, если мы проверим тривиальный пакет, как coreutilsв zesty (здесь) . мы можем видеть, что много вещей будет установлено /binрядом /usr/bin, но все же это может быть ссылка, о которой я не знаю.
Равексина
2
@Ravexina Arch Linux уже содержит символические ссылки / bin на / usr / bin
Дмитрий Кудрявцев,
1
Я думал, что люди поймут, что это выдуманная ситуация, я фактически не удалял свою /bin, я думал о том, что может случиться с кем-то еще (основываясь на другом вопросе, на который я ответил), затем я написал инструкцию, чтобы поделиться своими знаниями с другими :), хотя я ценю все комментарии, они также полезны для других людей, которые приходят, чтобы прочитать этот вопрос. Спасибо всем;)
Ravexina
1
У меня есть привычка всякий раз, когда я использую команду «rm -r» или любую другую команду, которая может иметь значительные последствия, я набираю команду и затем убираю руки из клавиатуры примерно на 3 секунды, по крайней мере, прежде чем нажать ВОЙТИ. Это дает мне возможность просмотреть его и убедиться, что все правильно введено, и я знаю, что он будет делать, что я планирую делать. В редких случаях во время этой паузы я решаю, что мне нужно стереть команду - не всегда, потому что это неправильная команда, а иногда потому, что мне сначала нужно выполнить некоторую проверку.
17

Ответы:

180

Является ли это возможным?

Ну, большинство тривиальных и важных утилит установлены в /bin, и теперь вы потеряли доступ ко всем из них. Фактически, если вы перезагрузите компьютер, ваша система больше не сможет загружаться.

В любом случае, мы собираемся исправить проблему и сделать /binсодержимое как можно ближе к тому, где оно было. Единственным отличием будут некоторые символические ссылки, которые мы тоже исправим.


Как?

Во-первых, мы должны chrootв вашу сломанную систему, но с небольшой разницей ! После этого мы получим список установленных пакетов в вашей системе, в которых есть какой-либо установленный файл в /binкаталоге, затем мы будем только загружать необходимые пакеты и извлекать необходимые файлы в /bin. Тогда мы будем готовы.

Например, после chrootэтого мы можем получить список пакетов, в которых установлены файлы при /binиспользовании:

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

И мы также можем использовать:

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

перечислить установленные файлы этими пакетами в /bin.

Затем мы просто создаем список всех пакетов, которые нам нужны, затем скачиваем их и распаковываем в /binнечто вроде:

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

Однако мы должны использовать скрипт для проверки всех установленных пакетов в нашей системе, потому что делать это вручную - просто безумие.

Поэтому я написал сценарий, который делает все, что нам нужно. Он находит все необходимые пакеты для восстановления /bin, показывает нам имя каждого пакета и связанные с ним файлы, к которым он принадлежит /bin. Вот скриншот:

Снимок экрана: список пакетов <code> / bin </ code>, выводимый моим скриптом

В конце мы решили переустановить все пакеты или только загрузить и распаковать необходимые файлы /bin(что является рекомендуемым вариантом):

Снимок экрана параметров, предоставленных моим скриптом

Вы можете получить копию этого скрипта или загрузить его напрямую .


Давайте начнем

корневой

Загрузите вашу систему с живого диска, который имеет ту же архитектуру, что и установленная вами Ubuntu, откройте терминал и получите root-доступ:

sudo -i

Смонтируйте свою rootфайловую систему (для меня это /dev/sda1):

mount /dev/sda1 /mnt

Нам понадобится подключение к Интернету, поэтому скопируйте resolv.confиз живого Ubuntu в ваш смонтированный корневой раздел:

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

Теперь скопируйте скрипт куда-нибудь на смонтированный раздел, например:

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

или вы можете скачать его, используя wget, и т. д. как:

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

Смонтировать другие необходимые пути:

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

И вот небольшая разница : как мы можем chrootсломать систему, если там нет /binкаталога? Какую оболочку мы должны запустить?

Так что создайте временный каталог bin. Например: имя bintmpвнутри вашей сломанной системы root:

mkdir /mnt/bintmp

Тогда связывай жизнь /binс этим:

mount --bind /bin /mnt/bintmp

Загрузите систему, установив в /bintmp/bashкачестве оболочки для входа в систему:

chroot /mnt /bintmp/bash

Экспортируйте /bintmpкак PATHпеременную среды:

export PATH=/bintmp:$PATH

Дайте скрипту исполняемый бит:

chmod +x restore-bin.sh

Запустите скрипт:

./restore-bin.sh

Дождитесь завершения поиска и ответьте на вопрос, который мы видели на скриншоте. Это начнет восстанавливать, /binи мы почти закончили.

После того, как это сделано, используйте CTRL+, Dчтобы выйти из chrootсреды и размонтировать смонтированные пути:

umount -R /mnt

Перезагрузите систему.

Восстановление ссылок внутри /bin

Теперь почти все файлы в /binкаталоге вернулись, за исключением около 5 символических ссылок, которыми управляет update-alternatives.

В вашей работающей системе запустите:

sudo update-alternatives --all

Он задает вам несколько вопросов; Вы можете просто нажать, ENTERчтобы принять их все.

И теперь мы закончили.

Ravexina
источник
30
Это, без сомнения, лучший ответ, который я видел в Ask Ubuntu. Вы очень любезны пойти на такую ​​большую работу, зная, что ОП находится в неудобной ситуации.
Нонни Мус
15
Ой, подождите, доктор. Я должен был понять, что ты это сделал.
Нонни Мус
Это потрясающе. Мне нравится, что дизайн SE не дает никаких намеков на то, что это вопрос с самоотдачей.
Педро А
5
@Hamsteriffic: он видит прямоугольник, содержащий имя ответчика (подпись): у него более темный фон, чего нет у постов, не связанных с ОП. Это касается комментариев, ответов и вопросов.
Руслан
27

Если ваша текущая система все еще имеет работающую оболочку и доступ к Интернету, это можно сделать с помощью инструментов, существующих в других местах системы. Я предполагаю, что вы только удалили /bin. /binконечно, есть самая удобная утилита, которую вы могли бы использовать в такой ситуации (busybox), но без этого нам придется проявить немного творчества.


Поскольку у вас уже есть работающая оболочка, и, поскольку sudoона /usr/binвключена, давайте запустим работающую корневую оболочку, прежде чем мы нанесем дополнительный ущерб. Но /bin/bashи большинство других оболочек ушли! К счастью, в Linux все еще есть копия оболочки, которую вы используете. Так:

sudo /proc/$$/exe

Строго говоря, нам не нужна корневая оболочка для большей части следующего. Но в любом случае.

Теперь dpkgвсе еще работает, по крайней мере, для определения, в каких пакетах есть файлы /bin:

dpkg -S /bin

Мы можем использовать его awkдля обработки и получения имен пакетов, xargsа также apt-getдля загрузки пакетов (все в /usr/bin). Если у вас есть временный каталог, который вы можете использовать, cdтам, потому что ваш текущий каталог будет немного грязным:

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

Теперь самая большая проблема, с которой мы сталкиваемся, - это /bin/tarотсутствие, и без него dpkgневозможно извлечь архивы. Мы можем пройти две трети пути, потому что:

  1. .debфайлы на самом деле являются arархивами (снова в /usr/bin):

    ar x tar_*.deb
    
  2. Состоит из двух .tar.*архивов dataи control:

    $ echo *.tar.*
    control.tar.gz data.tar.xz
    
  3. В то время как GZIP утилиты находятся в /bin, unxzв /usr/bin:

    unxz data.tar.xz
    

Теперь у нас есть data.tarфайл без tarизвлечения tarиз него.

Питон на помощь ! Вот где sudoдействительно нужно:

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

Теперь мы можем использовать dpkgдля извлечения оставшихся файлов deb, чтобы получить достаточно полный /bin:

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

Тем не менее, мы все равно должны сделать правильную установку файлов deb, чтобы символические ссылки и т. Д., Которые создавались бы пакетами, создавались заново:

sudo apt install --reinstall ./*.deb

Или же:

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

Примечания:

  1. Мы не можем использовать Python 2 для непосредственного извлечения data.tar.xzфайла, так как Python 2 поддерживает только сжатие gzip и bzip2. Python 3, однако, поддерживает его, поэтому вы можете использовать Python 3 напрямую без unxz:

    sudo python3 -c 'import tarfile; tarfile.open("data.tar.xz").extractall("/")'
    
  2. После возвращения /bin/tarвам по-прежнему необходимо извлечь некоторые файлы deb, прежде чем вы сможете их использовать apt-get: оболочки, coreutils и т. Д. Проще просто извлечь их все и переустановить позже.
Мур
источник
Я не проверял это, но я почти полностью прочитал это, это было потрясающе, на самом деле я пытался найти копию bash в памяти, я искал немного, я не нашел ничего интересного, и после того, как я увидел, что tar не в /usr/bin, я сказал, что я иду с chroot ... Удивительно.
Равексина
1
Вопрос, не /proc/$$/exeссылка на /bin/bash? как это работает при /binудалении? (Это работает, но как), я подумал, что это должна быть неработающая ссылка ... вот почему я оставил эту идею позади.
Равексина
1
PATH = / usr / lib / klibc / bin: $ PATH вернет вам путь cat и sh
Джошуа,
@ Джошуа И каждый из них статически связан! Приятно!
Муру
7

Вы можете временно поместить файлы с живого компакт-диска или другой системы в свою, /binчтобы сделать вашу систему пригодной для использования, а затем заменить их файлами из вашей установки Ubuntu, запустив apt-get install --reinstallпакеты, в которых есть что-то /bin.

Дмитрий Григорьев
источник
Это то, что я бы сделал. Живой DVD с тем же номером версии будет почти таким же, если не точно таким же, как установленный на данный момент. Если бы у меня был диск или версия USB Live, я бы мог сравнить их и опубликовать ответ, подобный вашему. Эта ветка является скорее теорией, если OP никогда не удалял / bin в первую очередь, что вполне возможно, поскольку он написал ответ в то же время, что и вопрос, по всей вероятности. Все еще очень хороший мысленный эксперимент и отличный стиль письма.
WinEunuuchs2Unix
Я рекомендую отредактировать этот ответ, чтобы дополнить его конкретными сведениями о том, как это сделать. (См. Также Как написать хороший ответ? Для общего совета о том, какие ответы считаются наиболее ценными в AskUbuntu.)
Дэвид Фёрстер,
1

Некоторые дополнения к этим прекрасному ответу , после того, как я встретил этот вопрос (наряду с стиранию /boot, /etc, /libи /lib64):

  • chrootтребует /libи /lib64должен присутствовать; в противном случае вы получите следующую ошибку:
    failed to run command ‘/bin/bash’: No such file or directory
    я скопировал их из ОС LiveCD, и у меня не возникло проблем с восстановлением. YMMV в зависимости от установленных вами пакетов в системе
  • Я не могу редактировать ответ, указанный выше, но есть опечатка:
    cp /etc/resolv.conf /mnt/etc/resolv.cof
    должно быть
    cp /etc/resolv.conf /mnt/etc/resolv.conf
  • /bootможет быть легко восстановлен с помощью инструментов Grub. Смотрите здесь .
  • Как этот ответ рекомендует, apt install --reinstall <package>это отличный способ , чтобы восстановить недостающие файлы /bin, /libи /lib64.
    • Некоторые пакеты , которые требуют повторной установки: libaio1, mysql-server, openvpn,vsftpd

Примечание для себя:
rm -rf folder /*это не то же самое, чтоrm -rf folder/*

mrtumnus
источник