问题描述
我正在研究名为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
的相关文件。这是一个截图:
最后,我们选择重新安装所有软件包,或者只下载并提取必要的文件到/bin
(这是推荐的选项):
您可以抓取a copy of this script或download 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
来处理它并获取软件包名称,并且可以使用xargs
和apt-get
下载软件包(全部在/usr/bin
中)。如果您有一个可以使用的临时目录,那么cd
,因为您的当前目录会有点混乱:
dpkg -S /bin | awk -F '[, :]' '{NF--}1' | xargs apt-get download
现在,我们遇到的最大问题是/bin/tar
丢失,如果没有它,dpkg
将无法提取存档。我们可以得到那里的two-thirds,因为:
-
.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 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
笔记:
-
我们不能使用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等。稍后可以轻松提取所有这些文件和re-install。
第三种解决办法
您可以暂时将Live CD或其他系统中的文件放入您的/bin
以使您的系统可用,然后通过运行apt-get install --reinstall
来处理/bin
中包含的软件包,将其替换为Ubuntu安装中的文件。