当前位置: 首页>>技术问答>>正文


意外删除/bin。我如何恢复它?

, ,

问题描述

我正在研究名为bin的目录。完成后,由于bin及其中的一些文件的所有权,我不小心跑了:

sudo rm -r /bin

代替:

sudo rm -r bin

看来我的手曾经在我输入的所有内容前添加了/

我怎样才能恢复我的/bin目录?

我想要属于我的Ubuntu的相同文件,我不喜欢从活动磁盘或其他正在运行的系统复制和粘贴它们。

最佳解决办法

可能吗?

那么,/bin中安装了大多数微不足道和重要的实用程序,现在您无法访问所有这些实用程序。事实上,如果您重新启动,您的系统将无法再使用boot-up。

无论如何,我们要解决这个问题,并尽可能使/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的相关文件。这是一个截图:

command-line,restore,ubuntu

最后,我们选择重新安装所有软件包,或者只下载并提取必要的文件到/bin(这是推荐的选项):

command-line,restore,ubuntu

您可以抓取a copy of this scriptdownload it directly


开始吧

chroot

使用与安装的Ubuntu具有相同体系结构的活动磁盘引导系统,打开终端并获得root访问权限:

sudo -i

安装root文件系统(对我来说,它是/dev/sda1):

mount /dev/sda1 /mnt

我们需要连接到互联网,因此请将resolv.conf从实时Ubuntu复制到挂载的根分区:

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

现在将脚本复制到挂载分区的某处,例如:

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

这里有一点小小的区别:当/bin目录中没有/bin目录时,我们如何才能将chroot分解为系统?我们应该运行哪个shell?

所以创建一个临时的bin目录。例如:在破损的系统根目录中命名为bintmp

mkdir /mnt/bintmp

然后将实况/bin绑定到:

mount --bind /bin /mnt/bintmp

在将/bintmp/bash设置为登录shell时将chroot插入系统:

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目录中的所有文件都回来了,除了由update-alternatives管理的大约5个符号链接之外。

在您的运行系统中,运行:

sudo update-alternatives --all

它会问你一些问题;您只需按ENTER即可全部接受。

现在我们完成了。

次佳解决办法

如果您当前的系统仍然具有运行shell和Internet访问权限,则可以使用系统中其他位置存在的工具来完成此操作。我假设你只删除了/bin/bin当然有最方便的工具,您可以在这种情况下使用(busybox),但没有这些,我们将不得不有点创意。


由于您已经有了一个运行中的shell,并且由于sudo位于/usr/bin中,所以让我们在进一步破坏之前让自己成为一个运行的根shell。但是/bin/bash和其他大部分炮弹都没了!幸运的是,Linux仍然有一个您正在使用的shell的in-memory副本。所以:

sudo /proc/$$/exe

严格地说,我们不需要根目录下面的大部分内容。但不管怎么说。

现在,dpkg仍然有效,至少可以找到哪些软件包在/bin中有文件:

dpkg -S /bin

我们可以使用awk来处理它并获取软件包名称,并且可以使用xargsapt-get下载软件包(全部在/usr/bin中)。如果您有一个可以使用的临时目录,那么cd,因为您的当前目录会有点混乱:

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

现在,我们遇到的最大问题是/bin/tar丢失,如果没有它,dpkg将无法提取存档。我们可以得到那里的two-thirds,因为:

  1. .deb文件实际上是ar归档文件(同样在/usr/bin中):

    ar x tar_*.deb
    
  2. 由两个.tar.*档案组成,datacontrol

    $ echo *.tar.*
    control.tar.gz data.tar.xz
    
  3. 虽然gzip实用程序在/binunxz/usr/bin

    unxz data.tar.xz
    

现在我们有一个没有tardata.tar文件从中提取tar

Python to the rescue!这是真正需要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文件,以便由包创建的符号链接等是re-created:

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之后,在使用apt-get之前,您仍然需要提取一些deb文件:shell,coreutils等。稍后可以轻松提取所有这些文件和re-install。

第三种解决办法

您可以暂时将Live CD或其他系统中的文件放入您的/bin以使您的系统可用,然后通过运行apt-get install --reinstall来处理/bin中包含的软件包,将其替换为Ubuntu安装中的文件。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/705.html,未经允许,请勿转载。