为什么可以删除整个文件系统?


24

犯了一个臭名昭著的错误,即通过删除整个文件系统sudo rm -rf /*,从造成的可怕破坏中恢复过来,并解决了我刚刚失去生命6年的事实,我开始想知道为什么甚至有可能这样做,以及可以采取什么措施来防止发生此错误。

向我建议的一种解决方案是从我的帐户撤消root用户访问权限,但这很不方便,因为许多命令都需要root用户访问权限,而当您每天必须运行几十个命令时,这会很烦人。

备份系统是显而易见的方法。但是还原备份还需要一些停机时间,并且根据您的系统,停机时间可能是数天或数周,在某些情况下这是不可接受的。

我的问题是:当用户尝试删除其文件系统时,为什么不执行确认?这样一来,当您实际想要执行此操作时,您只需按Y或Enter键即可,如果您不这样做,则不会损失所有内容。



20
“为什么甚至有可能这样做呢?” 为什么should't这可能吗?删除目录层次结构的内容完全有充分的理由,而其中的很多子集/几乎都无法删除(/etc/例如)。rm确定哪些目录可以轻易删除还是不容易删除,根本不是工作。
chepner

2
标题显示“为什么可以删除系统?” 而问题本身问“我的问题是:当用户尝试删除其文件系统时,为什么不执行确认?”。因此,这使问题不清楚。您的实际问题是哪个,因此我们至少知道要回答什么?请编辑您的帖子以澄清
Sergiy Kolodyazhnyy

3
这里实际上是什么问题?我可以看到三个:(1)为什么会这样?(2)如何防止这样做?以及(3)为什么不执行确认?-它们不是同一个问题,第一个是推理,第二个是工具。(第三个与第二个有关,但仍不完全相同。确认并不是防止某些事情的唯一方法。)
ilkkachu

10
如果您不要求问题作者澄清,请不要发表任何评论。我在这里看到许多自我祝贺的评论,解释了OP的错误是由于不知道标志的含义或没有备份或其他原因。我很高兴得知我们如此众多的用户足够聪明,可以进行备份并且不运行他们不了解的命令。这对他们来说绝对是很棒的选择,但对OP来说根本没有帮助,OP大概现在也已经学到了这一课。因此,让我们停止沉浸在自己的光辉中,而回答这个问题。
terdon

Answers:


16

rm是低级系统工具。这些工具的构建尽可能简单,因为它们必须存在于任何系统中。rm希望它具有众所周知的行为,尤其是在确认提示方面,以便可以在脚本中使用。

rm /*由于rm命令无法以这种形式显示,因此无法添加特殊情况进行提示。该*通配符是由外壳被传递到前扩大rm,所以这需要一个特殊情况的实际命令将像rm /bin /boot /dev /etc /home /initrd.img /lib /lib64 /lost+found /media /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var /vmlinuz。添加代码以检查这种情况(在不同的Linux上可能会有所不同)将是一个复杂的挑战,并且容易出现细微的错误。标准linux rm通过拒绝/不带该--no-preserve-root选项的删除,确实具有防止系统破坏的默认保护。

默认情况下,存在三种防止以这种方式删除系统的保护措施:

  1. 权限-普通用户将无法删除重要文件。你用sudo绕过了
  2. 目录-默认情况下,rm不会删除目录。您使用-r标志绕过了这个
  3. 写保护的文件-默认情况下,rm会在删除写保护的文件之前要求确认(这不会阻止所有损坏,但可能会在系统无法恢复之前提供提示)。您使用-f标志绕过了此保护

要删除文件夹中的所有内容,而不是运行rm /path/to/folder/*,请执行do rm -rf /path/to/foldermkdir /path/to/folder因为这将触发--preserve-root保护以及删除文件夹中的所有dotfiles


3
“ rm应该具有众所周知的行为”,实际上它是POSIX标准指定的工具之一。确切地说,“ he *通配符在传递给rm之前已由外壳程序进行了扩展”,因此添加对所有类型参数的检查(可能是指向实际目录和文件的符号链接)/将需要很多组合和考虑因素,因此不切实际。回到标准的想法,添加此类检查将破坏一致的行为
Sergiy Kolodyazhnyy

这就是为什么safe-rm要包装的原因rm:这样,它可以检查每个单独的参数(而不是整个随机命令行),确认它不在可配置的黑名单中,然后再rm使用已验证的参数进行调用。这既不是很复杂也不容易出错。
甜点

59

Meet safe-rm安装安全RM,“ rm命令周围的包装器,以防止意外删除”:

safe-rm通过rm使用包装器进行替换来防止重要文件的意外删除,该包装器将对给定的参数与永不删除的可配置文件和目录黑名单进行检查。

试图删除这些受保护文件或目录之一的用户将无法这样做,而将显示警告消息。(man safe-rm

如果上面的安装链接对您不起作用,请sudo apt install safe-rm改用。默认配置已经包含系统目录,让我们尝试rm /*例如:

$ rm /*
safe-rm: skipping /bin
safe-rm: skipping /boot
safe-rm: skipping /dev
safe-rm: skipping /etc
safe-rm: skipping /home
safe-rm: skipping /lib
safe-rm: skipping /proc
safe-rm: skipping /root
safe-rm: skipping /sbin
safe-rm: skipping /sys
safe-rm: skipping /usr
safe-rm: skipping /var
…

如您所见,这将防止您删除/home,我想您的个人文件存储在这里。但是,~如果您尝试直接删除它们或其子目录,它不会阻止您删除它们或其任何子目录。要添加~/precious_photos目录,只需添加其绝对路径,并将波浪号解析为safe-rm的配置文件/etc/safe-rm.conf,例如:

echo /home/dessert/precious_photos | sudo tee -a /etc/safe-rm.conf

对于您rm不带sudo1-f标志运行的情况,最好为您的shell 添加一个alias使rm-i标志为默认标志的外壳。这种方式rm要求每个文件在删除之前:

alias rm='rm -i'

一个类似的有用标志是-I,它仅警告“一次删除三个以上的文件之前,或者以递归方式删除时”,这“比侵入程度小-i,同时仍然可以防止大多数错误”:

alias rm='rm -I'

这些别名的一般危险是,您容易养成依靠它们来保存您的习惯,这在使用其他环境时可能会适得其反。


1:sudo忽略别名alias sudo='sudo '尽管可以通过定义别名来解决


25

确认已经在那里,问题出-f在命令中,即--force;当用户强制执行某项操作时,假定他们知道自己在做什么(很明显总是会出现错误)。

一个例子:

 rm -r ./*
 rm: remove write-protected regular file './mozilla_mvaschetto0/WEBMASTER-04.DOC'? N
 rm: cannot remove './mozilla_mvaschetto0': Directory not empty
 rm: descend into write-protected directory './pulse-PKdhtXMmr18n'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-bolt.service-rZWMCb'? n
 rm: descend into write-protected directory './systemd-private-     890f5b31987b4910a579d1c49930a591-colord.service-4ZBnUf'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-fwupd.service-vAxdbk'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-minissdpd.service-9G8GrR'? 
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-ModemManager.service-s43zUX'? nn
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-rtkit-daemon.service-cfMePv'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-systemd-timesyncd.service-oXT4pr'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-upower.service-L0k9rT'? n

--force选项不同:我将不会得到任何确认,并且文件将被删除。

问题是要知道命令及其参数,例如,在命令的导航中更多man(如果在教程中也找到了该命令),例如:第一次看到该命令时,tar xzf some.tar.gz我问自己:“这xzf是什么意思? ”

然后,我阅读了tar联机帮助页并发现了它。


我认为这无关紧要。在rm首次要求写保护文件或任何文件时,它可能已经删除了一大堆重要文件。
JonasSchäfer

1
因此,就我个人而言,我一直认为-f需要删除文件夹。我什至打开提示进行确认和投诉的提示,但得知这只是-r必需的。我想它rm -rf已经成为一种规范,因为它在脚本中非常有用(您不希望脚本因尝试删除不存在的内容而失败),因此您经常看到它,但是我想我们需要要警惕rm -r在外壳中仅用作我们的“默认”(可以理解的是,不应有您不理解的“默认”假设,尤其是对于sudo,但人们会是人,至少这是更安全的)。
上尉

2
Rmdir是删除文件夹的最安全方法
AtomiX84

rm默认情况下,它不要求确认,它仅向其请求写保护的目录和文件。如果您在计算机上运行该命令,则可能会删除许多自己的文件。如果需要rm确认,则需要传递-i参数。例如:rm -ir ./*
Dan

8

没有备份运行意味着您必须非常小心,不要犯任何错误。希望您的硬件永不失败。(即使RAID也无法使您免受RAM错误导致的文件系统损坏。)所以这是您的第一个问题。(我以为您已经意识到了,将来会做备份。)


但是您可以采取一些措施来减少发生此类错误的可能性:

  • 别名rm='rm -I'以提示是否删除3件以上的东西。
  • 别名mv和cp为mv -iand cp -i(这些的许多正常用例涉及覆盖目标文件)。
  • 使用别名sudo='sudo '对第一个参数进行别名扩展sudo

我发现rm -I它比有用得多rm -i。通常在正常使用过程中不会提示,因此在您没想到它时提示提示是一个更明显/更好的警告。使用-i(在我发现之前-I),\rm在确定正确键入命令之后,我习惯于键入以禁用别名扩展。

您不想养成依赖rm -i-I别名来保存您的习惯。您希望这条安全线永远不会被使用。如果我实际上是想交互式地选择要删除的匹配项,或者不确定我的glob是否可以匹配某些额外的文件,请手动输入rm -i .../*whatever*。(如果您所在的环境中没有别名,这也是一个好习惯)。

首先Enter输入ls -d /*foo*,然后再向上箭头键,以防止胖手指,然后rm -r在输入完毕后将其更改为。因此,命令行在rm -rf ~/任何时候都不会包含或类似的危险命令。您只需通过使用control-a,alt-d切换到行的开头并在完成命令部分的输入后添加或ls来“武装”它。rm-r-f~/some/sub/dir/

根据您要删除的内容,实际运行第ls -d一个,如果不添加任何内容,则不运行任何选项卡。您可能以rm(不带-r-rf)开头,所以它只是control-a /右控制键(或alt + f)/ space / -r

(习惯于使用bash / readline强大的编辑键绑定来快速移动,例如控制箭头或alt + f / b逐字移动,并使用alt +退格键或alt + d或control-w杀死整个单词。 -u杀死到该行的开头。如果走得太远,则使用control- /撤消编辑。当然,可以使用control-r / control-s搜索的向上箭头历史记录。)

避免使用,-rf除非您确实需要它以使有关删除只读文件的提示静音。

在按回车键之前,需要花更多时间思考sudo 尤其是如果您没有完整的备份,或者现在是必须从其中还原的不好时机。


6

好吧,简短的答案是不要运行这样的命令。

长期而言,这是自定义的一部分。基本上,有两个因素在起作用。一个事实是您可以自由修改所有文件。

第二个问题是rm命令提供了有用的语法糖,可以删除文件夹下的所有文件。

实际上,可以将其重新定义为Unix计算机的简单宗旨。一切都是文件。为了使事情变得更好,有一些访问控制,但是这些对您的使用会被覆盖

须藤

我想您可以添加一个别名或函数来确保永远不能运行它。


4

如果您的系统文件空间使用量不是很大(如今,“巨大”意味着“数百GB或更多”)会创建一些虚拟机实例,并始终在其中运行。恢复仅需要使用备份实例。

或者,您可以创建一个chroot监狱,并在其中进行工作。如果将其丢弃,您仍然需要一些恢复,但是使用运行中的(封闭式)系统可以更轻松地进行恢复。


这可能是最有效的答案,因为它可以防止任何损害,甚至第三方脚本也不受影响。您只需要担心实际的恶意软件。
PyRulez

换个角度思考。值得一问的是,为什么首先需要进行递归删除。也许我们真正需要的是一些脚本,删除一个项目,等等
罗兰·罗森

“值得一问的是,为什么首先需要进行递归删除。” 好吧,仅仅因为没有内置命令并不意味着您仍然不会犯错。第三方脚本可能会从某个目录中一个接一个地删除文件。还有其他方法可以使系统仅触摸一个文件。但是,至少rmsafe-rm帮助代替。
PyRulez

我对脚本的想法是,它将具有“项目”或类似内容的内置概念。也许您在项目根目录下会有一个名为的空文件.project_root,或者,如果文件系统支持,则在目录本身上有一个属性。然后,脚本将在文件树中查找项目根目录,并抱怨当前目录不在项目中。或者,如果所有项目都生活在同一位置,则脚本可能会要求您命名一个项目。您仍然可以删除错误的项目,但不能破坏整个系统。
Loren Rosen

...此外,的一种变体chroot是使用类似Docker的东西(我认为实际上是chroot在幕后使用)。对于您只需要读取的其他文件,请安装一个只读文件系统。
洛伦·罗森

3

rm这是一个非常老的Unix命令,可能在设计时没有考虑到用户友好性。当它具有权限时,它会尝试精确地执行所要求的操作。对于许多新用户来说,一个陷阱是他们经常看到代码,sudo而不是考虑使用它。直接修改文件一样的功能rmddchroot等需要格外小心使用。

如今,我喜欢使用trash(不使用sudo)来自trash-cli。它的功能类似于Windows的回收站,因为您可以轻松地检索意外删除的文件。Ubuntu已经有一个“垃圾桶”文件夹和“文件”内置的“垃圾桶移动”功能。

即使那样,您也可能会犯错误,因此请确保对整个文件系统进行备份。

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.