题 如何防止意外的rm -rf / *?


我跑了 rm -rf /* 不小心,但我的意思是 rm -rf ./* (注意斜线后的星星)。

alias rm='rm -i' 和 --preserve-root 默认情况下没有保存我,所以有任何自动保护措施吗?


我不是root并且立即取消了命令,但是在某处或某些地方有一些放松的权限,因为我注意到我的Bash提示已经破坏了。我不想依赖权限而不是root(我可能会犯同样的错误 sudo),我不想寻找神秘的错误,因为系统中某处丢失了一个文件,因此,备份和 sudo 很好,但我想为这个具体案例做些更好的事情。


关于思考两次并使用大脑。我实际上在使用它!但是我用它来解决一些涉及10种不同事情的复杂编程任务。我已经深深地沉浸在这项任务中,没有任何脑力来检查旗帜和路径,我甚至没有考虑命令和论据,我认为就像'空当前dir'这样的行为,我的大脑的不同部分将它们转化为命令,有时它会犯错误。我希望计算机纠正它们,至少是危险的。


156
2017-12-02 17:09




仅供参考,你也可以 rm -rf . /mydir 代替 rm -rf ./mydir 并杀死你所在的任何目录。我发现这种情况更常发生。 - user606723
使用枪类比,这个问题说请让枪识别我瞄准我的脚而不是火,但是我不想对我的脚瞄准我的脚一开始没有任何责任。枪支和电脑都是愚蠢的,如果你做了一件蠢事,你就会得到这些结果。沿着枪类比,除了警惕和练习之外,没有任何东西可以让你免于伤害自己。 - slillibri
@slillibri除此之外 rm 不是枪,它是一个计算机程序,它 可以 要足够聪明,以确定用户是否要删除一些重要文件并发出警告(就像你试图做的那样 rm -rf / 没有明星)。 - Valentin Nemcev
@slillibri枪有安全。问如何把更好的安全放在上面 rm 命令是一个完全合法的系统管理员问题。 - Gilles
sudo rm / bin / rm 不推荐,但会阻止大多数rm的 :-) - Paul


答案:


我遵循的一个技巧是放 # 在使用时开始 rm 命令。

root@localhost:~# #rm -rf /

这可以防止意外执行 rm 在错误的文件/目录上。验证后,删除 # 从最开始。这个技巧有效,因为在Bash中有一个词开头 # 导致该单词和该行上的所有剩余字符被忽略。所以命令被忽略了。

要么

如果你想阻止任何重要的目录,还有一个技巧。

创建一个名为的文件 -i 在那个目录中。如何创建这样一个奇怪的文件?运用 touch -- -i 要么 touch ./-i

现在试试 rm -rf *

sachin@sachin-ThinkPad-T420:~$ touch {1..4}
sachin@sachin-ThinkPad-T420:~$ touch -- -i
sachin@sachin-ThinkPad-T420:~$ ls
1  2  3  4  -i
sachin@sachin-ThinkPad-T420:~$ rm -rf *
rm: remove regular empty file `1'? n
rm: remove regular empty file `2'? 

在这里 * 将扩大 -i 到命令行,所以你的命令最终成为 rm -rf -i。因此命令会在删除前提示。你可以把这个文件放在你的 //home//etc/

要么

使用 --preserve-root 作为一种选择 rm。在里面 rm 包含在较新的 coreutils 包,此选项是默认选项。

--preserve-root
              do not remove `/' (default)

要么

使用 安全-RM

摘自网站:

Safe-rm是一种旨在防止意外删除的安全工具   通过用包装器替换/ bin / rm重要文件,检查   针对可配置的文件和黑名单的给定参数   永远不应删除的目录。

尝试删除其中一个受保护文件的用户或   目录将无法执行此操作并将显示警告   消息代替:

$ rm -rf /usr
Skipping /usr

215
2017-12-02 23:36



safe-rm看起来非常好,现在正在调查...... - Valentin Nemcev
安全的很整洁。这也是一个很好的伎俩 -i 文件。哈。傻傻的。 - EricR
令人惊讶的是在unix中完成了什么样的技巧。 - WernerCD
名为-i的创建文件绝对是纯粹的天才。大概一年前,当我不小心在VPS上运行rm -rf / etc / *时,我可以使用它...(幸运的是,我每晚拍摄快照,因此能够在45分钟内恢复)。 - David W
这是天才。巫术会 touch -- -rf - Mircea Vutcovici


你的问题:

我只是意外地运行了rm -rf / *,但我的意思是rm -rf ./*(注意斜线后的星号)。

解决方案: 不要那样做! 作为一种做法,不要使用 ./ 在路径的开头。斜杠不会为命令添加任何值,只会引起混淆。

./*意思是一样的 *,所以上面的命令写得更好:

rm -rf *

这是一个相关的问题。我经常看到以下表达式,有人认为 FOO 设置为类似的东西 /home/puppies。实际上,我在一个主要软件供应商的文档中看到了这一点。

rm -rf $FOO/

但如果 FOO 未设置,这将评估为 rm -rf /,它将尝试删除系统上的所有文件。尾部斜线是不必要的,因此实际上不要使用它。

以下内容将执行相同的操作,并且不太可能损坏您的系统:

rm -rf $FOO

我很难学会这些技巧。当我14年前拥有我的第一个超级用户帐户时,我不小心跑了 rm -rf $FOO/ 从shell脚本中销毁系统。另外4名系统管理员对此进行了调查并说,'是的。每个人都这样做过一次。现在这是您的安装媒体(36个软盘)。去解决它。'

其他人在这里推荐解决方案 --preserve-root 和 safe-rm。但是,这些解决方案并非适用于所有Un * xe-varients,并且可能无法在Solaris,FreeBSD和MacOSX上运行。此外, safe-rm 要求您在所使用的每个Linux系统上安装其他软件包。如果你依赖 safe-rm,当你开始一份新工作而他们没有工作时会发生什么 safe-rm 安装?这些工具是一个拐杖,依靠已知的默认值并改善您的工作习惯要好得多。


42
2017-12-02 18:58



我的朋友告诉我他从不使用 rm -rf *。他总是首先更改目录,并使用特定目标。原因是他经常使用贝壳的历史,并担心在他的历史中有这样的命令可能会在错误的时间弹出。 - haggai_e
@haggai_e:好小费。当我刚接触Unix时,我跑过一次遇到了一个bug rm -rf * 也删除了 . 和 ..。我是root用户,这遍历了较低的目录,如 ../../..,并且非常具有破坏性。我试着非常小心 rm -rf * 自从。 - Stefan Lasiewski
rm -rf $FOO 如果你需要,将无济于事 rm -rf $FOO/$BAR。 cd $FOO && rm -rf $BAR 会有所帮助,虽然它会更长。 - Victor Sergienko
@VictorSergienko,用bash,如何指定 ${FOO:?},如在 rm -rf ${FOO:?}/ 和 rm -rf ${FOO:?}/${BAR:?}。它会阻止它翻译成 rm -rf /。我在答案中有更多关于此的信息 这里。 - A-B-B
@haggai_e:我发现这是关于这个主题的最佳建议之一。我用手指烧了我的手指 rm -rf * 在for循环中,错误地更改为错误的目录并最终删除其他内容。如果我会使用一个特定的目标,它将有很小的机会删除错误的东西。 - richk


由于这是“Serverfault”,我想这样说:

如果您有数十台或更多服务器,并且拥有大量管理员/用户, 有人 要去 rm -rf 要么 chown 错误的目录。

您应该有一个计划,以尽可能少的MTTR备份受影响的服务。


30
2017-12-02 20:42



你应该使用VM或备用盒来练习恢复 - 找出哪些不起作用并改进所述计划。我们正在进行两周一次的重启 - 因为我们的大楼里有电力输出,每次都很痛苦。通过对所有机架进行一些计划停机,我们已经将它从几天的运行时间缩短到现在大约3个小时 - 每次我们都知道自动执行/修复init.d脚本等等。 - Danny Staple
并在VM上尝试此命令。这真有趣!但先拍快照。 - Stefan Lasiewski


最好的解决方案包括改变你的习惯而不使用 rm 直。

一种方法是运行 echo rm -rf /stuff/with/wildcards* 第一。检查通配符的输出是否合理,然后使用shell的历史记录执行上一个命令而不使用 echo

另一种方法是限制 echo 指出你将要删除的内容非常明显的情况。而不是删除目录中的所有文件,删除该目录并创建一个新目录。一个好方法是将现有目录重命名为 DELETE-foo,然后创建一个新目录 foo 有适当的权限,最后删除 DELETE-foo。此方法的另一个好处是,您在历史记录中输入的命令是 rm -rf DELETE-foo

cd ..
mv somedir DELETE-somedir
mkdir somedir                 # or rsync -dgop DELETE-somedir somedir to preserve permissions
ls DELETE-somedir             # just to make sure we're deleting the right thing
rm -rf DELETE-somedir

如果您真的坚持删除一堆文件,因为您需要保留该目录(因为它必须始终存在,或者因为您没有权限重新创建它),请将文件移动到其他目录,然后删除该目录。

mkdir ../DELETE_ME
mv * ../DELETE_ME
ls ../DELETE_ME
rm -rf ../DELETE_ME

(打那个 Alt键+ 键。)

从内部删除目录会很有吸引力,因为 rm -rf . 因此很短,因此错别字的风险很低。不幸的是,典型系统不允许您这样做。你可以 rm -rf -- "$PWD" 相反,具有更高的拼写错误风险,但大多数都导致删除任何东西。请注意,这会在shell历史记录中留下危险的命令。

只要你可以,使用版本控制。你没有 rm,你 cvs rm 或者其他什么,这是可以撤销的。

Zsh有运行前提示你的选项 rm 使用参数列出目录中的所有文件: rm_star_silent (默认情况下已启用)执行前提示 rm whatever/*,和 rm_star_wait (默认情况下关闭)会增加10秒的延迟,在此期间您无法确认。如果您打算删除某个目录中的所有文件,则此用途有限,因为您已经期望提示。它可以帮助防止错别字 rm foo * 对于 rm foo*

还有更多的解决方案,包括改变 rm 命令。这种方法的局限性在于,有一天你将拥有真实的机器 rm 你会自动打电话 rm,您对预期确认安全......接下来您将恢复备份。


23
2017-12-02 22:33



mv -t DELETE_ME -- * 更加万无一失。 - Tobu
@Giles没用 rm 直接是好建议!一个更好的选择是 使用 find 命令。 - aculich
如果你需要保留目录,你可以通过使用简单地完成 find somedir -type f -delete 这将删除所有文件 somedir 但是会离开目录和所有子目录。 - aculich


你可以随时做一个别名,如你所说:

what_the_hell_am_i_thinking() {
   echo "Stop." >&2
   echo "Seriously." >&2
   echo "You almost blew up your computer." >&2
   echo 'WHAT WERE YOU THINKING!?!?!' >&2
   echo "Please provide an excuse for yourself below: " 
   read 
   echo "I'm sorry, that's a pathetic excuse. You're fired."
   sleep 2
   telnet nyancat.dakko.us
}

alias rm -fr /*="what_the_hell_am_i_thinking"

您还可以将它与命令行Twitter客户端集成,通过擦除您的硬盘来提醒您的朋友您几乎如何羞辱自己 rm -fr /* 作为根。


18
2017-12-02 17:16



为telnet miku.acm.uiuc.edu +1 - Ali
别名echo =“telnet miku.acm.uiuc.edu” - kubanczyk
我一定不能老去......有什么意义 telnet miku.acm.uiuc.edu? - Kyle Strand
试一试,找出答案。这是非破坏性的。如果你像你应该的那样偏执,那么在VM中运行。 - Naftuli Kay
-1你不能别名包含空格的命令,更不用说/ *这是一个无效的名字 - xenithorb


是的:不要以root身份工作,在表演之前总是三思而后行。

另外,看看像 https://launchpad.net/safe-rm


15
2018-02-26 05:50



提到在编辑中以root身份工作 - Valentin Nemcev
@Valentin:o_O !! - Jonathan Rioux


防止意外的最简单方法 rm -rf /* 是避免一切使用 rm 命令!事实上,我一直都很想跑 rm /bin/rm 完全摆脱命令!不,我不是很滑稽。

而是使用 -delete 的选择 find 命令,但首先在删除文件之前,我建议您预览要删除的文件:

find | less

请注意,在现代版本中 find 如果省略目录的名称,它将隐式使用当前目录,因此上述内容相当于:

find . | less

一旦你确定这些是你想要删除的文件,你就可以添加 -delete 选项:

find path/to/files -delete

所以,不仅如此 find  使用更安全,也更具表现力,因此,如果您只想删除与特定模式匹配的目录层次结构中的某些文件,可以使用这样的表达式进行预览,然后删除这些文件:

find path/to/files -name '*~' | less
find path/to/files -name '*~' -delete

学习和使用有很多充分的理由 find 除了更安全 rm,所以如果你花时间学习使用,你会感谢以后 find


15
2017-12-03 22:44



非常有趣的讨论。我喜欢你的方法并制作了一些小片段。它效率极低,因为它最多可以调用3次,但对我来说这是一个不错的开始: github.com/der-Daniel/fdel - Daniel Hitzel


在这个帖子中有一些非常糟糕的建议,幸运的是大多数都被拒绝了。

首先,当你需要成为root用户时,成为root-sudo,各种别名技巧会让你变弱。更糟糕的是,它们会让你不小心。学会以正确的方式做事,停止依赖别名来保护你。有一天,你会在一个没有你的训练轮并炸掉一些东西的盒子上扎根。

第二 - 当你扎根时,把自己想象成驾驶满载学童的公共汽车。有时你可以通过收音机摇滚歌曲,但有时候你需要双向看,减慢速度,并仔细检查所有镜子。

第三 - 你几乎没有  不得不 rm -rf  - 你更有可能想要 mv something something.bak 要么 mkdir _trash && mv something _trash/

第四 - 永远 ls 你之前的通配符 rm  - 在永远摧毁它之前看一些东西并不是什么疯狂的事。


14
2017-12-02 19:57



+1使用 ls。 - Sachin Divekar
@eventi我同意在这个帖子中有一些可怕的建议和难看的黑客。在破坏它之前看一些东西绝对是一个好主意,但有一个 甚至更好的方法来使用 find 命令。 - aculich
我没有看到发现更简单或更安全,但我喜欢你的 find . -name '*~' 例。我的观点是 ls 将列出相同的glob rm 将使用。 - eventi


这是我的标准,专门用于rm环境中的regexp,但在这种情况下它可以节省你。

我经常做 echo foo*/[0-9]*{bar,baz}* 首先,看看正则表达式将匹配什么。一旦我有输出,然后我返回命令行编辑和更改 echo 至 rm -rf。一世 从来没有使用过 rm -rf 在未经测试的正则表达式上


11
2017-12-02 19:05



请比较: linuxmanpages.com/man3/regex.3.php  linuxmanpages.com/man3/glob.3.php - bukzor
好的,我在找什么?您是否指出文件匹配的正则表达式语法与例如perl中使用的语法不同(有时通过不同的名称调用)?还是我错过了一些其他观点?我为思绪的缓慢而道歉,这是周六早上的第一件事! - MadHatter
你称之为“regexp”的这些东西实际上是整体。它不是一个不同的正则表达式语法;它不是正则表达式。 - bukzor
当然可以提出这个论点;但是,从维基百科有关正则表达式的文章中,我发现“许多现代计算系统在文件系统中匹配文件名时提供通配符。这是许多命令行shell的核心功能,也称为通配” - 请注意使用“也称为”,在我看来,它表明调用包含元字符的标记来匹配一个或多个文件名regexp并没有错。我同意globbing是一个更好的术语,因为除了在文件名匹配中使用正则表达式之外,它并不意味着什么。 - MadHatter
@MadHatter在删除之前检查哪些文件匹配是一个很好的建议,但有一个 更安全,更富表现力的方式来做到这一点 find 命令。 - aculich


此问题的解决方案是定期备份。无论何时你生产出一些你不想冒失败的东西,都要备份它。如果您发现定期备份太痛苦,那么简化流程以免造成痛苦。

例如,如果您使用源代码,请使用类似的工具 git 镜像代码并在另一台机器上保存历史记录。如果您处理文档,请使用脚本 rsync把你的文件送到另一台机器上。


9
2017-12-03 23:02



像btrfs这样的写时复制文件系统也可以提供帮助。您可以轻松设置本地运行的简单自动快照轮换(除了外部备份)。 - malthe


似乎降低此风险的最佳方法是像大多数GUI一样进行两阶段删除。也就是说,将rm替换为将事物移动到垃圾目录(在同一卷上)的东西。然后经过足够的时间清理垃圾,发现任何错误。

在Unix StackExchange上讨论了一个这样的实用程序trash-cli, 这里


6
2017-12-02 17:15



这是我在每台机器上安装的第一件事。它应该是默认的删除工具,rm仅在您需要立即删除某些内容时使用。我很遗憾它还没有起飞,但有一天它会。可能是在一个非常公开的rm实例导致一个无法通过备份解决的巨大问题之后。可能是恢复所花费的时间是一个重要因素。 - Gerry
+1使用Linux 20年后,我仍然认为应该有某种垃圾桶行为 rm。 - Shovas