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

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

我正在处理一个名为 的目录bin。完成后,由于 的所有权bin以及其中的一些文件,我意外地运行了:

sudo rm -r /bin

代替:

sudo rm -r bin

似乎我的手习惯于/在我输入的每一个字前面加一个。

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

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

答案1

是否可以?

好吧,大多数琐碎而重要的实用程序都安装在 中/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 具有相同架构的活动磁盘启动您的系统,打开终端并获取 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?我们应该运行哪个 shell?

因此,创建一个临时的 bin 目录。例如:bintmp在损坏的系统根目录中命名:

mkdir /mnt/bintmp

然后将直播绑定/bin到那里:

mount --bind /bin /mnt/bintmp

将 chroot 进入系统并设置/bintmp/bash为您的登录 shell:

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接受所有问题。

现在我们已经完成了。

答案2

如果您当前的系统仍有正在运行的 shell 和互联网访问,则可以使用系统其他地方现有的工具来完成此操作。我假设您只删除了/bin/bin当然,在这种情况下您可以使用最方便的实用程序 (busybox),但如果没有它,我们就必须发挥一点创造力。


由于您已经有一个正在运行的 shell,并且由于sudo在 中/usr/bin,因此在我们造成进一步破坏之前,让我们自己获取一个正在运行的 root shell。但是/bin/bash大多数其他 shell 都消失了!幸运的是,Linux 仍然有您正在使用的 shell 的内存副本。所以:

sudo /proc/$$/exe

严格来说,我们不需要 root shell 来完成接下来的大部分操作。但无论如何。

现在,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就无法提取档案。我们可以完成三分之二的工作,因为:

  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文件。tartar

Python 来救援!这才是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:shell、coreutils 等等。更容易的方法是先将它们全部提取出来,然后再重新安装。

答案3

你可以暂时地将文件从实时 CD 或其他系统放入您的系统中以使您的系统可用,然后通过运行包含内容的软件包/bin将它们替换为来自 Ubuntu 安装的文件。apt-get install --reinstall/bin

答案4

一些补充这个优秀的答案,在我遇到此问题之后(以及删除、/boot/etc):/lib/lib64

  • chroot需要/lib/lib64存在;否则您将收到以下错误:
    failed to run command ‘/bin/bash’: No such file or directory
    我从 LiveCD OS 复制了这些内容,恢复时没有任何问题。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-serveropenvpnvsftpd

提醒自己:
rm -rf folder /*rm -rf folder/*

相关内容