Rav*_*ina 97 command-line restore
我正在处理一个名为bin. 完成后,由于所有权bin和其中的一些文件,我不小心运行了:
sudo rm -r /bin
Run Code Online (Sandbox Code Playgroud)
代替:
sudo rm -r bin
Run Code Online (Sandbox Code Playgroud)
似乎我的手过去常常/在我键入的所有内容前面添加一个。
我怎样才能恢复我的 /bin目录?
我想要属于我的 Ubuntu 的相同文件,我不喜欢从活动磁盘或其他正在运行的系统中复制和粘贴它们。
Rav*_*ina 186
好吧,大多数琐碎和重要的实用程序都安装在 中/bin,现在您无法访问所有这些实用程序。事实上,如果您重新启动,您的系统将无法再启动。
无论如何,我们将解决这个问题并使/bin的内容尽可能接近它所在的位置。唯一的区别是一些我们也将修复的符号链接。
首先,我们应该chroot进入你的破系统,但有细微的差别!之后,我们将获得系统上已安装软件包的列表,其中/bin目录中有任何已安装文件,然后我们将只下载所需的软件包并将必要的文件解压缩到/bin. 那我们就完了。
例如,在 之后chroot,我们可以获取已安装文件的软件包列表/bin:
dpkg --search /bin | cut -f1 -d: | tr ',' '\n'
Run Code Online (Sandbox Code Playgroud)
我们还可以使用:
dpkg --listfiles PACKAGE-NAME | grep "^/bin/" # or awk '$0 ~ "^/bin/
Run Code Online (Sandbox Code Playgroud)
列出这些包中安装的文件/bin。
然后我们简单地创建一个我们需要的所有包的列表,然后下载它们并将它们解压缩到/bin:
xargs apt download < list-packages
dpkg-deb -x PACKAGE .
mv ./bin/* /bin
Run Code Online (Sandbox Code Playgroud)
但是,我们必须使用脚本来检查系统上所有已安装的软件包,因为手动执行此操作简直是疯了。
所以我写了一个脚本来完成我们需要的一切。它为我们找到所有需要恢复的包/bin,向我们显示每个包的名称及其所属的相关文件/bin。这是一个屏幕截图:
最后,我们选择重新安装所有软件包或仅将必要的文件下载并解压缩到/bin(这是推荐的选项):
使用与安装的 Ubuntu 具有相同架构的实时磁盘启动系统,打开终端并获得 root 访问权限:
sudo -i
Run Code Online (Sandbox Code Playgroud)
挂载你的root文件系统(对我来说是/dev/sda1):
mount /dev/sda1 /mnt
Run Code Online (Sandbox Code Playgroud)
我们需要连接到互联网,所以resolv.conf从 live Ubuntu复制到你挂载的根分区:
cp /etc/resolv.conf /mnt/etc/resolv.conf
Run Code Online (Sandbox Code Playgroud)
现在将脚本复制到已安装分区上的某个位置,例如:
cp /media/ubuntu/usb/restore-bin.sh /mnt/restore-bin.sh
Run Code Online (Sandbox Code Playgroud)
或者您可以使用wget等下载它,例如:
wget https://git.io/v9fRm -O /mnt/restore-bin.sh
Run Code Online (Sandbox Code Playgroud)
挂载其他必要的路径:
mount --bind /dev /mnt/dev
mount --bind /sys /mnt/sys
mount -t proc /proc /mnt/proc
Run Code Online (Sandbox Code Playgroud)
这是一个细微的区别:chroot当那里没有/bin目录时,我们如何才能到一个损坏的系统?我们应该运行哪个shell?
所以创建一个临时的bin目录。例如:bintmp在您损坏的系统根目录中命名:
mkdir /mnt/bintmp
Run Code Online (Sandbox Code Playgroud)
然后将 live 绑定/bin到:
mount --bind /bin /mnt/bintmp
Run Code Online (Sandbox Code Playgroud)
将 chroot 设置/bintmp/bash为登录 shell时进入系统:
chroot /mnt /bintmp/bash
Run Code Online (Sandbox Code Playgroud)
将 导出/bintmp为您的PATH环境变量:
export PATH=/bintmp:$PATH
Run Code Online (Sandbox Code Playgroud)
给脚本可执行位:
chmod +x restore-bin.sh
Run Code Online (Sandbox Code Playgroud)
运行脚本:
./restore-bin.sh
Run Code Online (Sandbox Code Playgroud)
等待搜索完成,然后回答我们在屏幕截图中看到的问题。它将开始恢复/bin,我们几乎完成了。
完成后,使用CTRL+D退出chroot环境并卸载已安装的路径:
umount -R /mnt
Run Code Online (Sandbox Code Playgroud)
重新启动系统。
/bin现在/bin目录中的几乎所有文件都回来了,除了大约 5 个由update-alternatives.
在您正在运行的系统中,运行:
sudo update-alternatives --all
Run Code Online (Sandbox Code Playgroud)
它会问你一些问题;您只需按ENTER即可全部接受。
现在我们完成了。
mur*_*uru 30
如果您当前的系统仍然有一个正在运行的 shell 和互联网访问,这可以使用系统上其他地方现有的工具来完成。我假设你只删除了/bin. /bin当然有您可以在这种情况下使用的最方便的实用程序(busybox),但没有它,我们将不得不有点创意。
既然您已经有一个正在运行的 shell,并且sudo在 中/usr/bin,那么在我们进一步破坏之前让我们自己获得一个正在运行的 root shell。但是/bin/bash,大多数其他贝壳都不见了!幸运的是,Linux 仍然有您正在使用的 shell 的内存副本。所以:
sudo /proc/$$/exe
Run Code Online (Sandbox Code Playgroud)
严格来说,接下来的大部分内容我们不需要 root shell。但无论如何。
现在,dpkg仍然有效,至少用于查找哪些包中有文件/bin:
dpkg -S /bin
Run Code Online (Sandbox Code Playgroud)
我们可以使用awk处理,并得到了包名,并xargs和apt-get下载包(所有/usr/bin)。如果您有一个可以使用的临时目录,那么cd在那里,因为您的当前目录会变得有点乱:
dpkg -S /bin | awk -F '[, :]' '{NF--}1' | xargs apt-get download
Run Code Online (Sandbox Code Playgroud)
现在,我们遇到的最大问题/bin/tar是缺少它,dpkg如果没有它,就无法提取档案。我们可以做到三分之二,因为:
.deb文件实际上是ar档案(再次在/usr/bin):
ar x tar_*.deb
Run Code Online (Sandbox Code Playgroud)由两个.tar.*档案组成,data以及control:
$ echo *.tar.*
control.tar.gz data.tar.xz
Run Code Online (Sandbox Code Playgroud)当 gzip 实用程序在/bin,unxz中时/usr/bin:
unxz data.tar.xz
Run Code Online (Sandbox Code Playgroud)现在我们有一个data.tar文件,无需tar从中提取tar。
Python 来救援!这是sudo真正需要的地方:
$ sudo python -c 'import tarfile; tarfile.open("data.tar").extractall("/")'
$ echo /bin/*
/bin/tar
Run Code Online (Sandbox Code Playgroud)
现在我们可以使用dpkg提取剩余的 deb 文件来获得一个合理完整的/bin:
for i in *.deb; do dpkg-deb -x "$i" /; done
Run Code Online (Sandbox Code Playgroud)
但是,我们仍然应该正确安装 deb 文件,以便重新创建由包创建的符号链接等:
sudo apt install --reinstall ./*.deb
Run Code Online (Sandbox Code Playgroud)
或者:
sudo dpkg -i *.deb
sudo apt-get install -f
Run Code Online (Sandbox Code Playgroud)
笔记:
我们不能使用 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("/")'
Run Code Online (Sandbox Code Playgroud)/bin/tar,您仍然需要提取一些 deb 文件才能使用apt-get:shell、coreutils 等。更容易提取所有这些文件并稍后重新安装。你可以暂时把文件从Live CD或者其他系统到您/bin,使您的系统中使用,然后通过运行与你的Ubuntu的安装文件替换它们apt-get install --reinstall对于具有东西在包/bin。