意外删除/ 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
的相关文件。 这是一个截图:
最后,我们选择重新安装所有软件包,或者只下载并将必要的文件解压缩到/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
来处理它并获取包名,并使用xargs
和apt-get
来下载包(全部在/usr/bin
)。 如果你有一个可以使用的临时目录,请在那里cd
,因为你当前的目录会变得有点乱:
dpkg -S /bin | awk -F '[, :]' '{NF--}1' | xargs apt-get download
现在,我们遇到的最大问题是缺少/bin/tar
,如果没有它, dpkg
无法提取存档。 我们可以得到三分之二的路,因为:
-
.deb
文件实际上是ar
档案(再次在/usr/bin
):ar x tar_*.deb
-
由两个
.tar.*
档案,data
和control
:$ echo *.tar.* control.tar.gz data.tar.xz
-
虽然gzip实用程序位于
/bin
,但unxz
位于/usr/bin
:unxz data.tar.xz
现在我们有一个没有tar
的data.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
笔记:
-
我们不能使用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("/")'
- 在返回
/bin/tar
,你仍然需要在使用apt-get
之前提取一些deb文件:shell,coreutils等。更容易提取所有这些并稍后重新安装。
您可以暂时将实时CD或其他系统中的文件放入/bin
以使您的系统可用,然后通过运行apt-get install --reinstall
来apt-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
丢失文件的好方法。- 一些需要重新安装的软件包:
libaio1
,mysql-server
,openvpn
,vsftpd
- 一些需要重新安装的软件包:
注意自我:
rm -rf folder /*
与rm -rf folder/*