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


81

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


18
rm -rf /没有不会删除任何东西--no-preserve-root
muru 2015年

47
我最初在Linux上的经历是制作Ubuntu vm,这样我就可以“ rm -rf /”。我建议您尝试一下。它的设置非常快,可以确保主机安全,并且在您眼前观看OS崩溃的各个部分时非常有趣。非常令人满意。
DJMcMayhem

21
让我想起了我最喜欢的低估的错误报告:bugzilla.redhat.com/show_bug.cgi?id=1202858 “预期结果:Squid重新启动。实际结果:所有文件都在计算机上删除。”

9
您应该阅读Unix Recovery Legend。只要您仍然登录到Shell,系统就不会完全崩溃!
200_success

2
@gerrit 我做到了。:)
muru 2015年

Answers:


79

/bin/rm删除都没关系。它只运行一次,到那时它都已加载到内存中,其他所有将删除内容继续发送到文件系统和磁盘所需的条件也是如此。


补充工具栏/更新:根据David Hoelzer的回答(并在评论中提到),/bin/rm用于指向的硬链接的inode 会一直保持到rm完成为止(因为Linux处于打开状态),但是这一事实无关紧要;磁盘的状态根本不重要。

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

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


无论如何,这也是为什么您可以删除当前内核的软件包而不会导致计算机崩溃的原因。只要您安装其他版本,它就可以启动。

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

find / -exec rm {} \;

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


7
正如@DavidHoelzer解释的那样,未链接的文件不必已经在内存中即可继续工作。内核知道有一个打开的文件句柄,因此它将文件数据保留在其中,以满足所有请求(包括页面调入),直到关闭最后一个句柄为止。
Andrew Medico

4
@Desty,不,只要/bin/rm距离不够近,直到最后一批都没有结束,那就不会成功;-exec ... {} +(不需要使用反斜杠转义)仍然会导致多次执行;不是每个文件一个,而是根据ARG_MAX可以容纳的参数数量,每批一个。
Charles Duffy 2015年

6
@Oli,这与分页无关;引用计数器链接到索引节点,而不是目录条目,并且打开的文件句柄被视为引用(与硬链接相同),从而防止索引节点被释放。文件大小根本不是一个因素,即使根本没有交换空间(因此也没有分页),也会发生这种情况。
Charles Duffy 2015年

2
@CharlesDuffy不管您是否有交换空间,分页都​​将用于所有内存映射文件。这包括所有可执行文件和库。实际上,缺少交换空间实际上意味着更多的内存映射文件分页正在进行。
kasperd 2015年

2
@CharlesDuffy是的,大小确实无关紧要。内存映射文件不会导致文件的任何内容被加载,直到被访问。如果需要,可以再次释放用于加载文件的已访问部分的内存,此后,如果再次访问,则将从文件中加载该内存。因此,只要映射了文件,文件确实确实必须保留在文件系统上,并且对于一页文件来说,其行为与对于足以跨越整个地址空间的文件的行为相同。(对于动态链接所需的写时复制映射,细节有些复杂。)
kasperd 2015年

57

我没有在Ubuntu上尝试过此命令(出于明显的原因),所以我不确定Ubuntu是否允许执行。

是的 rm -rf / --no-preserve-root在直接在计算机上打开的root会话中运行,而我也ssh使用root帐户通过另一台计算机进行连接。

发生的是,您开始收到很多消息,例如:

rm:无法删除“ / ...”:不允许操作

要么:

rm:无法删除“ / ...”:设备或资源正忙

在此处输入图片说明

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

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

在计算机上,保留四个目录:

  • /dev。这是设备文件的存储位置。
  • /proc—内核创建的内存中文件系统。
  • /run,是守护程序的标准化文件系统位置。
  • /sys。这使您可以获得有关系统及其组件的信息。

这意味着剩下的东西不多了,要做的事情也不多。您不能ls(尽管使用时Tab,仍显示目录和文件的名称)。您可以cd在不同的目录中,也可以在目录中,echo但是诸如之类的命令cat不再可用。

也没有sudo

shutdown -h now并且reboot消失了,所以您唯一的选择似乎是手动关闭机器。exit即使注销()显示出漂亮的“注销”文字,也无法正常工作。

尝试重新启动计算机后,会看到一个不错的GRUB错误15,然后什么也没有发生,这时您可能会开始认为rm可能对系统造成了不良影响。

在此处输入图片说明

你也可以做

不,等等,不要在您的机器上这样做!

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

部署结束后,您便可以使用一个环境。如果最终销毁了它,没关系:您再次部署计算机,两分钟后您可以继续。

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

快照的好处是您可以在几毫秒内拍摄一张快照。回滚快照需要更长的时间,但通常只需几秒钟。这使实验变得更加轻松快捷。

该实验不限于操作系统本身。您可以做涉及软件的各种事情。得到了可疑的应用程序?在VM中进行测试-如果是病毒,则不会造成任何危害。是否要测试数据库上的某个操作,因为它可能会影响环境?在VM中进行测试。

如果您是在真实的非测试计算机上执行该操作怎么办?

坏事发生了。请注意,这样做rm可以保护您免受自身伤害:rm -rf /无效:您需要使用--no-preserve-root。但是,如果您实际上错误地删除了所有内容,该怎么办?

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

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

如200_success注释中的文章所述,如果您行事明智,即使没有备用PC也可以将机器收回。如果您只关心数据,那么我就不会打扰-使用备用PC恢复数据要容易得多。


VirtualBox支持磁盘快照。
内森·奥斯曼

1
请注意,病毒通常是为检测VM而设计的,因此我不建议您使用此病毒检测过程。一个小问题:剩下的四个目录不是“真实”目录,对吗?它们实际上不在硬盘上吗?运行此命令后,硬盘驱动器上还有什么?
raptortech97

2
@ raptortech97 rm并没有真正清除硬盘驱动器上的内容,它只是从文件系统树中“取消链接”(取消关联)磁盘上的实际数据,将其标记为空闲(以便最终可能由于正常的计算机使用而被覆盖)。因此,如果您说的话,rm -rf ~只要您迅速采取行动(例如使用extundelete),就不会迷失一切。您可以将其视为邮箱中“已删除”文件夹的更为不可靠的版本,如果您等待的时间不长,则可以找回东西,但最终它将被清除。
托马斯

@ raptortech97另一方面,如果由于某些原因您没有使用rmbut shred,那么它就结束了很多,尽管您可能有时间意识到错误并中止,因为切碎需要更长的时间。
托马斯

5
保留的目录很可能是某种形式的挂载点或其他形式的挂载点。继续起作用的命令是bash内置命令,而不是单独的二进制文件。因此,当ls不见了,for i in /*; do echo $i; done应该工作。要替换,cat您可以使用类似的命令while read i; do echo $i; done < /proc/self/maps
MvG 2015年

25

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

链接数才是真正重要的。在UNIX系统上删除文件时,实际的系统调用是unlink。实际情况是指向该索引节点的链接计数(文件命名层中文件名的数量)减少了。当链接计数达到零时,文件系统知道已删除文件。

当文件被删除时,rm它还将编辑目录文件(是的,它只是一个文件,其中包含文件名和索引节点以及其他一些对于此答案不重要的位)。但是,实际上是通过取消链接释放磁盘资源。

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

另一个有趣的效果是,当一个inode的链接数大于零,但在文件命名层中没有指向它的索引时,会发生什么。从某种意义上说,这是一个很好的隐藏文件:)。要访问它,您将不得不使用低级的东西来按索引节点编号而不是名称进行引用(因为没有索引),或者使用十六进制编辑器编辑目录条目以指向索引节点。

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


换一种说法,链接计数不为零,因为打开文件会在/ proc中添加链接。
OrangeDog 2015年

@OrangeDog,即使卸载procfs,此行为仍然存在。
Charles Duffy 2015年

1
@OrangeDog Charles Duffy是正确的。/ proc中的文件句柄修改索引节点,而是调整链接数。
David Hoelzer,2015年

/ proc和/ sys是当前系统(内核)状态的反映。仅选择对文件和目录的操作实际上会更改系统状态。
CVn

18

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

rm不只是命令 这是一个可在中找到的程序PATH

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

  • 您致电(以root身份) rm -rf /
  • 程序的实例rm使用参数-rf/
  • 基于这些参数,程序将rm开始其操作(遍历已安装/分区中的所有内容,然后递归删除对其的引用[对技术性表示抱歉;]))
  • 完成后,将rm卸载程序实例
  • 此时,内存中唯一的东西就是以前加载的程序(例如bash,如果您在Ubuntu,桌面环境,内核,驱动程序等中打开了终端)
  • 如果您尝试调用任何其他命令(在Linux中,它使其成为一个独立程序),则它将失败,因为在PATH位置中找不到这样的程序(并且PATH位置不再存在)。但是,一旦加载,一切仍将运行

只是为了了解其工作原理,请尝试在ubuntu(在Virtualbox中),一些脚本和PHP操作码缓存上安装LAMP,然后调用此错误命令。令人惊讶的是(如果您很幸运,并且您的操作码缓存不会注意到php文件被删除),您仍然可以通过apache网络服务器从外部访问php脚本!

PS:这个邪恶的命令甚至以root身份运行,不会删除everything,它无法从中删除某些内核特权进程/proc,也无法从/dev系统中以文件形式显示的设备中删除某些内容。实际上,root并没有我们想象的那么全能,而内核却是。

PPS:另外,您还想拥有locked删除尝试时另一个进程处理过的文件。


在Linux上,您可以以root身份运行时当然可以删除设备节点。但是,是的,您不能从/proc其中删除任何内容,因为它是只读文件系统。同样适用于/sys。我相信您也无法删除挂载点。
布赖恩

@AlexKey我建议进行编辑以弄清“非内核嵌入式命令”的含义(或完全避免使用该短语)。这听起来像你说有可以通过命令通过被直接执行内核,使他们总是工作,无论什么壳。(这是因为你可能知道,但很多读者可能不,不是这样的:当你运行如下命令cd,这将调用内置的外壳由名-该命令被内置到外壳,而不是内核。)你Alt + SysRq是“命令”吗?
伊莱亚·卡根

@Brian取决于发行版吗?我曾在各种发行版中工作,但有趣的是,它多次犯了这个错误。正如我在检查了/的剩余物后所记得的那样,/ dev中仍然有东西,但是可能是诸如cdrom或floppy之类的东西
Alexey Kamenskiy 2015年

@EliahKagan因为我试图保持发行版独立,所以我使用了这个术语。这意味着并非在所有系统上,cli命令都意味着外部程序。但是,谢谢您指出这一点,我将澄清这一点。
Alexey Kamenskiy 2015年

@AlexKey我相信您将无法删除/dev/pts它,因为它是安装点。(还有一个只读文件系统。)
Brian

1

一旦硬盘中的所有内容全部清除,内核仍然可以正常工作,但由于没有设备,程序,命令等,因此仍然存在问题。

该操作系统将无法正常工作。

确实,Oli所说的是,该命令被加载/执行到内存中,除非您终止该进程(当然,如果kill命令仍然存在^^),也没有什么能阻止它。


4
为什么内核会卡住?MainMa的答案提出了其他建议,并支持我的期望。
MvG 2015年

4
程序从内存而不是硬盘驱动器运行。直到重新启动内核才知道有什么问题。
phyrfox

好吧,也许我需要更改我使用的词,内核或多或少地被“卡住了”,而没有设备,程序等。如果您不在根控制台的前面,您就无法做坏事,即使如此控制台,你不能做坏事。但是,我同意,我会改变自己的措辞,因为这会引起误解。
s1mmel 2015年

0

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

Selinux是强制性的访问控制,这意味着,在很多情况下,root用户实际上没有比系统上的任何其他用户强大的破坏系统的能力。

Selinux是在内核中强制执行的。您必须妥协内核才能解决它。

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

出于这个原因,Android的更高版本具有Selinux强制执行。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.