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

我正在处理名为bin的目录。 我完成后,由于bin和一些文件的所有权,我不小心跑了:

 sudo rm -r /bin 

代替:

 sudo rm -r bin 

似乎我的手习惯在我输入的所有内容之前添加/

如何恢复我的/bin目录?

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

可能吗?

好吧,大多数琐碎和重要的实用程序都安装在/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 

我们需要连接到Internet,因此将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目录时,我们怎么能chroot到一个破碎的系统? 我们应该运行哪个shell?

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

 mkdir /mnt/bintmp 

然后将live /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目录中的文件都回来了,除了大约5个由update-alternatives管理的符号链接。

在运行的系统中,运行:

 sudo update-alternatives --all 

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

现在我们完成了。

如果您当前的系统仍具有正在运行的shell和Internet访问权限,则可以使用系统上其他位置存在的工具来完成此操作。 我假设你只删了/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.*档案, datacontrol

     $ echo *.tar.* control.tar.gz data.tar.xz 
  3. 虽然gzip实用程序位于/bin ,但unxz位于/usr/bin

     unxz data.tar.xz 

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

拯救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 ,你仍然需要在使用apt-get之前提取一些deb文件:shell,coreutils等。更容易提取所有这些并稍后重新安装。

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

在遇到此问题后(以及删除/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 是恢复/bin/lib/lib64丢失文件的好方法。
    • 一些需要重新安装的软件包: libaio1mysql-serveropenvpnvsftpd

注意自我:
rm -rf folder /*rm -rf folder/*