‘rm -rf /’如何删除系统中的所有文件?

我没有在Ubuntu上尝试过这个命令(原因很明显),所以我不确定Ubuntu是否会允许它执行。 但它以删除所有内容而闻名。 出于好奇,内核和/bin被删除后会发生什么? rm如何维护运行时堆栈? rm如何设法与文件系统通信并完成删除? 它如何与硬件通信?

删除/bin/rm并不重要。 它只运行一次,到那时它全部加载到内存中,就像继续向文件系统和磁盘发送删除所需的一切一样。


边栏/更新:根据David Hoelzer的回答 (并在评论中提到),用于指向的hardlink /bin/rm的inode将保持正常直到rm完成(因为Linux保持打开状态) 这个事实无关紧要; 磁盘的状态根本不重要。

二进制文件在运行之前加载到内存中。 即使您可以手动销毁rm磁盘数据,也不会影响或阻止删除完成(假设您没有使磁盘不可用)。

不知道inode或hardlink是什么? 这就是我解决问题的答案。


无论如何,这也是为什么你可以在没有计算机内爆的情况下删除当前内核的软件包的原因。 只要您安装了不同的版本,它就能够启动。

同样,这是有效的,因为rm只被调用一次。 /bin/rm死后,以下内容失败,因为它会为每个文件名调用一次:

 find / -exec rm {} \; 

也就是说, find / -exec rm -rf {} +find / -print0 | xargs -0 rm -rf find / -print0 | xargs -0 rm -rf也可能都失败,因为它们都有参数限制,这意味着它们只会在再次调用之前删除许多文件。 在旅途中的某个时刻, /bin/rm可能会在其余文件被删除之前到期( 并被释放)。 虽然不能保证。 如果/bin/是最后输入的目录,这些方法可以工作。

我没有在Ubuntu上尝试过这个命令(原因很明显),所以我不确定Ubuntu是否会允许它执行。

我做到了。 rm -rf / --no-preserve-root在直接在机器上打开的根会话中运行,而我也通过ssh从另一台机器连接,也使用root帐户。

会发生什么事情,你开始得到很多消息,如:

rm:无法删除’/ …’:不允许操作

要么:

rm:无法删除’/ …’:设备或资源繁忙

在此处输入图像描述

令人惊讶的是, ssh连接一直打开,直到操作结束。 只有当我关闭连接并尝试重新打开它时才会出现错误:

从套接字读取失败:由对等方重置连接

在机器上,剩下四个目录:

  • /dev 。 这是存储设备文件的位置。
  • /proc -in-memory由内核创建的文件系统。
  • /run ,守护进程的标准化文件系统位置。
  • /sys 。 这允许您获取有关系统及其组件的信息。

这意味着没有多少剩余,并没有太多可做的。 你不能(虽然使用Tab时 ,仍会显示目录和文件的名称)。 你可以在不同的目录中cd ,也可以echo东西,但是像cat这样的命令不再可用。

也没有sudo

shutdown -h nowreboot消失了,所以你唯一的选择似乎是手动关闭机器。 注销( exit )不起作用,即使它显示一个很好的“注销”文本。

一旦你尝试重新启动机器,就会出现一个很好的GRUB错误15,然后,没有任何反应,此时你可能会开始认为你的rm可能对你的系统做了一些坏事。

在此处输入图像描述

你也可以这样做

不,等等,不要在你的机器上做!

你可以做的是运行虚拟机 。 虚拟机具有使实验变得非常容易的好处。 由于您使用的是Ubuntu,因此您可能对vmbuilder感兴趣。 这是一个允许您在几分钟内部署虚拟机的工具(官方文档声称它可以在大约一分钟内完成),但实际时间,即使在快速硬件上,也是大约两到三分钟。

部署结束后,您就拥有了可以玩的环境。 如果你最终破坏它,那没关系:你再次部署机器,两分钟后你就可以继续了。

如果您使用VMWare等软件,您可能也对快照感兴趣(请注意,免费的VMWare Player没有此function;您必须购买VMware Workstation)。 请注意,Hyper-V是免费的并且支持快照(但您必须运行Windows)。

快照的好处是你可以在几毫秒内完成一个。 回滚到快照需要更长时间,但通常只需几秒钟。 这使得实验变得更加容易和快捷。

该实验不限于操作系统本身。 你可以做各种涉及软件的事情。 得到了可疑的申请? 在VM中测试它 – 如果是病毒,它不会造成任何伤害。 想要测试数据库上的操作,因为它可能会影响环境? 在VM中测试它。

如果你在真正的非测试机器上做到这一点怎么办?

坏事发生了。 请注意, rm保护您自己: rm -rf /将无法工作:您需要使用--no-preserve-root 。 如果你真的错误地取消了所有东西呢?

rm只取消链接文件 ,但数据仍然存在于硬盘上。 这使得以后可以恢复它(这就是为什么当它们不再工作时不应该丢弃带有敏感数据的硬盘)。

这意味着您只需拥有一台带硬盘盒的备用PC即可实际恢复几乎所有文件。 重要的是避免将任何内容写入硬盘以进行恢复:您编写的数据将覆盖未链接的文件。

正如200_success评论中的文章所指出的那样 ,如果你表现得很聪明,你甚至可以在没有备用PC的情况下恢复机器。 如果您只关心数据,我不会打扰 – 使用备用PC恢复它更容易。

原因是文件命名层(你用ls看到的)实际上只是为了你的方便。 文件系统驱动程序和内核只关心inode是什么。 当按名称引用文件时,它会立即转换为包含所有元数据的inode,包括权限,磁盘上的数据块,所有者ID,组ID和链接计数。

链接数是真正重要的。 在UNIX系统上删除文件时,实际的系统调用是unlink 。 引擎盖下发生的事情是指向该inode的链接计数(文件命名层中的文件名数)递减。 当链接计数达到零时,文件系统知道文件被删除。

rm删除文件时,它也会编辑目录文件(是的,它只是一个包含文件名和inode的文件,以及一些对此答案不重要的其他位)。 但是,实际释放磁盘资源的是取消链接。

这导致了一些其他有趣的效果。 首先,可以打开一个链接数为零的文件。 当rm -rf /删除/bin/rm的条目时会发生这种情况。 文件已打开(有一个文件句柄),但inode标记为已删除(链接计数= 0)。 在文件句柄关闭之前,不会释放和重用磁盘资源。

另一个有趣的效果是当你有一个链接数大于零但在文件命名层中没有指向它的inode时会发生什么。 从某种意义上说,这是一个非常好的隐藏文件:)。 要访问它,您必须使用低级别来通过inode编号而不是名称(因为没有)来引用它,或者使用hex编辑器编辑指向inode的目录条目。

第三个有趣的效果是如果将链接计数减少到零但是仍然指向inode的目录条目会发生什么。 如果你愿意,我会留给你试验。 但显然,最后两个都导致文件系统处于不一致状态。

以前的答案很好,但我想澄清一个细节:

rm不仅仅是一个命令。 这是一个在PATH找到的程序。

因此,执行时会发生以下情况:

  • 你打电话(作为根) rm -rf /
  • 程序rm实例在内存中加载参数-rf/
  • 基于这些参数,程序rm开始运行(遍历挂载/分区中的所有内容并递归删除对它的引用[抱歉技术性;)])
  • 一旦完成,就卸载rm程序的实例
  • 在这一点上,内存中唯一的东西是之前加载的程序(例如,如果你在Ubuntu中打开了终端,桌面环境,内核,驱动程序等等)
  • 如果您尝试调用任何其他命令(在Linux的情况下使其成为独立程序),它将失败,因为在PATH位置中找不到此类程序(并且PATH位置不再存在)。 然而,一旦加载的所有东西仍将运行

只是为了理解它是如何工作的,尝试在ubuntu(在Virtualbox中)安装LAMP,一些脚本和PHP操作码缓存,然后调用这个邪恶的命令。 令人惊讶的是(如果你足够幸运并且你的操作码缓存不会注意到php文件删除)你仍然可以通过apache webserver从外部访问php脚本!

PS:这个邪恶的命令甚至以root身份运行不会删除everything ,它无法从/proc删除某些内核特权进程,也无法删除系统中出现的/dev设备中的一些内容,如文件。 事实上,root并不像我们想象的那样全能,另一方面内核也是如此。

PPS:另外,作为第二个想法,您还将拥有在删除尝试时被另一个进程locked的文件。

一旦从硬盘驱动器中擦除所有内容,内核仍然可以正常工作,但由于没有设备和程序,命令等等,所以内存仍然存在。

操作系统将不再起作用。

Oli说,这是正确的,命令被加载/执行到内存中,除非你杀死这个进程,否则什么都不会阻止它(当然,如果kill命令仍然存在^^)。

请注意,如果系统有selinux和selinux处于强制模式,并且selinux的策略设置正确; 然后什么都不会发生。

Selinux是强制访问控制,这意味着,在许多方面,root用户实际上没有比系统上任何其他用户更多的破坏系统的能力。

Selinux在内核中强制执行; 你必须妥协内核才能绕过它。

在设计良好且具有良好Selinux策略的系统上,root将无法在系统上做很多事情。

由于这个原因,后来的Android版本让Selinux强制执行。