问题描述
我没有在Ubuntu上试过这个命令(显而易见的原因),所以我不确定Ubuntu是否允许它执行。但它以删除所有内容而闻名。出于好奇,当内核和/bin
被删除时会发生什么? rm
如何维护运行时栈? rm
如何管理与文件系统通信并完全删除?它如何与硬件通信?
最佳解决思路
/bin/rm
被删除并不重要。它只能运行一次,到那时它会全部加载到内存中,正如其他所有必须继续将删除发送到文件系统和磁盘一样。
补充工具栏/更新:根据David Hoelzer’s answer(并在评论中提到),硬链接/bin/rm
用来指向的inode将保持正确,直到rm
完成(因为Linux保持打开状态),但事实并非如此;磁盘的状态根本不重要。
二进制文件在运行之前被加载到内存中。即使您可以手动销毁rm
磁盘数据,也不会影响或停止删除操作(假设您不会使磁盘不可用)。
No idea what an inode or hardlink are? This is the answer where I worked it out.
无论如何,这也是为什么你可以删除当前内核的软件包而不会造成计算机崩溃的原因。只要你安装不同的版本,它就可以启动。
再一次,这是有效的,因为rm
只被调用一次。在/bin/rm
死亡后,以下情况会失败,因为它会为每个文件名称调用一次:
find / -exec rm {} \;
也就是说,find / -exec rm -rf {} +
和find / -print0 | xargs -0 rm -rf
也可能失败,因为它们都有参数限制,这意味着它们只会在再次调用之前删除多个文件。在旅途中的某个时刻,/bin/rm
可能会在其他文件被删除之前到期(并被释放)。虽然不能保证。如果/bin/
是输入的最后一个目录,这些方法可以工作。
次佳解决思路
I haven’t tried this command on Ubuntu (for obvious reasons) so I am not sure if Ubuntu will allow its execution.
我做到了。 rm -rf / --no-preserve-root
正在直接在机器上打开的根用户会话中运行,而我也通过另一台机器上的ssh
连接,并使用root帐户连接。
会发生什么是你开始收到很多消息,如:
rm: cannot remove ‘/…’: Operation not permitted
要么:
rm: cannot remove ‘/…’: Device or resource busy
令人惊讶的是,ssh
连接保持开放直到操作结束。只有当我关闭连接并试图重新打开时出现错误:
Read from socket failed: Connection reset by peer
在机器上,剩下四个目录:
-
/dev
。这是存储设备文件的地方。 -
内核创建的
/proc
-in-memory文件系统。 -
/run
,一个守护进程的标准化文件系统位置。 -
/sys
。这使您可以获取有关系统及其组件的信息。
这意味着剩下的东西并不多,在那里没有太多的事情要做。你不能ls
(尽管当使用Tab
时,仍然显示目录和文件的名字)。您可以在不同的目录中使用cd
,也可以使用echo
,但cat
等命令不再可用。
没有sudo
。
shutdown -h now
和reboot
也消失了,所以您唯一的选择似乎是手动关闭机器。注销(exit
)不起作用,即使它显示一个不错的”logout”文本。
一旦你尝试重启机器,你会看到一个很好的GRUB错误15,然后什么也没有发生,此时你可能会开始认为你的rm
可能对你的系统做了一些坏事。
你也可以这样做
不,等等,不要在你的机器上做!
你可以做的是运行一个虚拟机。虚拟机具有使实验变得非常简单的好处。由于您使用的是Ubuntu,因此您可能会对vmbuilder感兴趣。这是一个允许您在几分钟内部署虚拟机的工具(官方文档声称它可以在“大约一分钟”内完成),但即使在快速硬件上,实际时间也只是two-three分钟。
一旦部署结束,你就有了一个可以玩的环境。如果最终破坏它,则无关紧要:您再次部署机器,两分钟后可以继续。
如果您使用VMWare等软件,您可能也会对快照感兴趣(请注意,免费的VMWare Player不具备此功能;您必须购买VMware Workstation)。请注意,Hyper-V是免费的并支持快照(但您必须运行Windows)。
快照的好处是你可以在几毫秒内完成一个快照。回滚到快照需要更长的时间,但通常只需几秒钟。这使得实验变得更加简单快捷。
这个实验不仅限于操作系统本身。你可以做各种涉及软件的事情。有一个可疑的应用程序?在VM中测试它 – 如果它是病毒,它不会造成任何伤害。想要测试数据库上的操作,因为它可能会影响环境?在VM中测试它。
如果你是在一台真正的non-test机器上做到这一点,该怎么办?
坏事发生。请注意,rm
可以保护您免受您的伤害:rm -rf /
无法工作:您需要使用--no-preserve-root
。不过,如果你真的实现了删除所有东西,那怎么办?
rm
只会取消链接文件,但数据仍然存在于硬盘上。这使得稍后恢复它成为可能(这就是为什么当他们不再工作时不应该丢弃带有敏感数据的硬盘的原因)。
这意味着您只需拥有一台带有硬盘驱动器机箱的备用电脑即可恢复几乎所有文件。重要的是避免将任何东西写入硬盘来恢复:您编写的数据将覆盖未链接的文件。
As noted by the article in 200_success’s comment,如果您聪明行事,即使没有备用电脑,也可以让机器恢复正常。如果你只关心数据,那么我不会打扰 – 用备用PC恢复它更容易。
第三种解决思路
原因在于文件命名层(您看到的是ls
)仅仅是为了您的方便。文件系统驱动程序和内核只关心inode是什么。当文件按名称引用时,会立即将其转换为包含所有元数据(包括权限,磁盘上的数据块,所有者ID,组ID和链接计数)的inode。
链接数是真正重要的。在UNIX系统上删除文件时,实际的系统调用是unlink
。在底层发生的是,指向该索引节点的链接计数(文件命名层中的文件名的数量)递减。当链接计数达到零时,文件系统知道文件被删除。
当文件被rm
删除时,它也将编辑目录文件(是的,它只是一个文件,其中包含文件名和inode,以及其他一些对此答案不重要的位)。但是,实际上释放磁盘资源是不连接的。
这导致了一些其他有趣的效果。首先,可以打开链接数为零的文件。这发生在rm -rf /
删除/bin/rm
条目时。文件打开(有一个文件句柄),但inode被标记为删除(链接计数= 0)。磁盘资源不会被释放并重新使用,直到文件句柄关闭。
另一个有趣的效果是,当链接数大于零的inode没有指向它的文件命名层时,会发生什么情况。从某种意义上说,这是一个非常好的隐藏文件:)。为了访问它,你必须使用低级别的参数来通过inode编号来引用它,而不是通过名称(因为没有一个)或者编辑一个目录项来使用十六进制编辑器指向inode。
第三个有趣的效果是,如果将链接数减少到零,但是仍然指向inode上的目录条目,会发生什么情况。如果你愿意的话,我会留给你试验一下。显然,最后两个都导致文件系统处于不一致的状态。
第四种思路
以前的答案很好,但我想澄清一个细节:
rm
不只是一个命令。这是一个在PATH
中找到的程序。
因此,执行时发生的情况如下:
-
你打电话(作为根)
rm -rf /
-
程序
rm
实例加载到内存中,参数为-rf
和/
-
基于这些参数程序
rm
开始其操作(遍历挂载/分区中的所有内容并递归移除对它的引用[对技术性抱歉;])) -
一旦完成,
rm
程序的实例将被卸载 -
此时内存中唯一的东西就是之前加载的程序(例如,如果在Ubuntu,桌面环境,内核,驱动程序等中打开了终端,则为bash)
-
如果您尝试调用任何其他命令(在Linux使其成为独立程序的情况下),它将失败,因为在PATH位置中找不到此类程序(并且PATH位置不再存在)。然而,一旦加载一切仍然会运行
为了理解它是如何工作的,请尝试在ubuntu上(在Virtualbox中)安装LAMP,一些脚本和PHP操作码缓存,然后调用这个邪恶的命令。令人惊讶的是(如果你足够幸运,你的操作码缓存不会注意到php文件的删除),你仍然可以通过apache webserver从外部访问php脚本!
PS:这个邪恶的命令,甚至跑了作为根本不会删除everything
,它不能删除/proc
一些内核权限的进程,不能从您的显示系统上的文件/dev
设备删除一些东西。事实上,根并不像我们想象的那样全能,核心则是另一方面。
PPS:同样作为第二个想法,在删除尝试时,另一个进程仍然会有locked
文件。