我正在处理一个名为 的目录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
。以下是屏幕截图:
最后我们选择重新安装所有软件包或者仅下载并提取必要的文件/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
来处理它并获取包名称,以及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
现在我们有一个无需从中提取的data.tar
文件。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
,您仍然需要提取一些 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-server
openvpn
vsftpd
- 一些需要重新安装的软件包:
提醒自己:
rm -rf folder /*
与rm -rf folder/*