Випадково видалено / смітник. Як відновити його?


91

Я працював над каталогом bin. Після того, як я закінчив, через право власності binта деякі файли в ньому я випадково запустився:

sudo rm -r /bin

Замість:

sudo rm -r bin

Здається, мої руки звикли додавати /перед усім, що я набираю.

Як я можу відновити /binкаталог?

Я хочу, щоб ті самі файли, що належать моєму Ubuntu, мені не подобається копіювати та вставляти їх з живого диска чи іншої запущеної системи.


3
Хіба /binна сьогодні Ubuntu не є просто символьним посиланням /usr/bin? Отже, все, що вам потрібно зробити, - це повернути симпосилання назад?
Мюзер

3
@Muzer Я працюю 16.04, і /binце не символічне посилання на /usr/binце, я думаю, це було б проти FHS. також якщо ми перевіримо тривіальний пакет, як coreutilsу zesty (тут) . ми можемо бачити, що багато речей буде встановлено /binпоряд із /usr/bin, але все-таки це може бути посилання, про яке я не знаю.
Ravexina

2
@Ravexina Arch Linux вже посилається / bin to / usr / bin
Дмитро Кудрявцев

1
Я думав, що люди зрозуміють, що це складена ситуація, я її фактично не усунув /bin, я вважав щось, що могло трапитися з ким-небудь іншим (На підставі іншого запитання, на яке я відповів), тоді я написав інструкцію поділитися своїми знаннями з іншими :), хоча всі коментарі я ціную, вони також корисні іншим, хто приходить прочитати це питання. Дякую всім;)
Равексіна

1
У мене з'явилася звичка щоразу, коли я використовую команду "rm -r" або будь-яку іншу команду, яка могла б мати суттєві наслідки, я набираю команду, а потім віддаляю руки від клавіатури приблизно на 3 секунди принаймні до удару Вхід. Це дає мені шанс переглядати це і переконатися, що я все правильно набрав і що я знаю, що це зробить те, що я планую зробити. У рідкісних випадках під час паузи я вирішую, що мені потрібно стерти команду - не завжди тому, що це неправильна команда, а іноді тому, що мені потрібно спочатку зробити деяку перевірку.
ajb

Відповіді:


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(що є рекомендованою опцією):

Скріншот варіантів, що задаються моїм сценарієм

Ви можете захопити копію цього сценарію або завантажити його безпосередньо .


Давайте розпочнемо

chroot

Завантажте свою систему живим диском, який має таку ж архітектуру, що і встановлений Ubuntu, відкрийте термінал і отримайте кореневий доступ:

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каталогу? Яку оболонку потрібно запустити?

Тому створіть тимчасовий каталог бін. наприклад: названий bintmpу вашому зламаному корені системи:

mkdir /mnt/bintmp

Потім прив’яжіть живий /binдо цього:

mount --bind /bin /mnt/bintmp

Chroot в систему, встановлюючи /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щоб прийняти їх усіх.

І ось ми закінчили.


30
Це, без сумніву, найкраща відповідь, яку я бачив у Ask Ubuntu. Ви надзвичайно люб'язно ходити на стільки робіт, знаючи, що ОП знаходиться в незручній ситуації.
Nonny Moose

15
О, зачекайте, т. Д. Я мав би зрозуміти, що ти це зробив.
Nonny Moose

Це дивно. Мені подобається, як дизайн SE зовсім не дає натяку на те, що це питання з самовідповіддю.
Педро A

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для вилучення решти файлів деб, щоб отримати достатньо повний /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 тощо. Простіше просто витягнути їх і встановити наново.

Я його не перевіряв, але я майже повністю прочитав його, це було приголомшливо, насправді я спробував знайти копію баш в пам'яті, я трохи пошукав, нічого цікавого не знайшов і після того, як побачив, що дьоготь - це ні /usr/bin, я сказав, що б я не ходив із хротом ... Дивовижно.
Равексіна

1
Питання, не /proc/$$/exeпосилання на /bin/bash? як це працює, коли /binвидаляється? (Це працює, але як), я думав, що це має бути зламана ланка ... саме тому я залишив цю ідею позаду.
Ravexina

3
@Ravexina не отримала повної відповіді, але: чим симпосилання / proc / <pid> / exe відрізняється від звичайних посилань?
муру

1
PATH = / usr / lib / klibc / bin: $ PATH поставить кота і повернеться на твій шлях
Джошуа

@Joshua І кожен з них статично пов'язаний! Приємно!
муру

7

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


Це я би робив. Живий DVD, що має той самий номер версії, буде майже таким же, якщо не зовсім таким, як встановлений поточний. Якби у мене був диск або версія USB Live, я міг би порівняти їх і опублікувати відповідь, як ваш. Цей потік є більшою мірою теорією, якщо ОП ніколи не видаляв / бін, в першу чергу, що є можливістю, оскільки він відповів, коли він написав відповідь одночасно з питанням. Ще дуже приємний продуманий експеримент та відмінний стиль написання.
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можна легко відновити за допомогою інструментів для грабування. Дивіться тут .
  • Як ця відповідь рекомендує, apt install --reinstall <package>це відмінний спосіб , щоб відновити відсутні файли /bin, /libі /lib64.
    • Деякі пакети , які вимагають повторної установки: libaio1, mysql-server, openvpn,vsftpd

Зауваження до себе:
rm -rf folder /*не те саме, щоrm -rf folder/*

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.