从什么时候开始 POSIX 和 GNU rm 不删除 /?

ter*_*don 25 gnu history posix rm

几年来,除非使用选项调用GNUrm实用程序,/否则它不会删除--no-preserve-root。然而,这个命令rm -rf /在很长一段时间内都被认为是危险的集体潜意识,人们仍然经常将其称为“可怕”的命令。

我想知道这个rm不能删除的规则是什么时候/出现的。我检查了 POSIX 规范,我可以看到,虽然POSIX:2008包含此安全功能,但POSIX:2001没有。由于POSIX规范的在线版本不时更新,随着每个新的子发布,我也检查了回程机,找到了2010年的POSIX:2008相关页面,并能够确认rm无法删除的规则/当时已经上市了。

所以,我的问题是:

  • rm不能删除的规则是什么时候/添加到 POSIX 规范中的?它是在单一 UNIX 规范第 4 版的原始 2008 版中还是在修订版中添加的?
  • 这个限制是rm什么时候添加到 GNU 的?我很确定它是在它被添加到 POSIX 之前,但它是什么时候发生的?

Sté*_*las 30

您可以在线找到 POSIX 2008 所有版本的 HTML 版本:

这是在 2008 版中添加的。

技术勘误一般不添加新功能。

您可以看到以前的版本 ( http://pubs.opengroup.org/onlinepubs/009695399/utilities/rm.html ) (POSIX 2004) 没有该文本。

新文本在2003-05-09 奥斯汀集团会议上被接受,以纳入标准的后续修订版。

要求由Sun Microsystems公司的约翰·贝克在三月份同一年(链路需要OpenGroup的注册,也见增强请求号5在这里)。

约翰贝克在 2003 年 3 月 11 日星期二写道:

@ page 820 line 31681-31683 section rm comment {JTB-1}

Problem:

Defect code :  3. Clarification required

An occasional user mistake, with devastating consequences, is to
write a shell script with a line such as:
      rm -rf $VARIABLE1/$VARIABLE2
or
      rm -rf /$VARIABLE1
without verifying that either variable is set, which can lead to
      rm -rf /
being the resulting command.  Since there is no plausible
circumstance under which this is the desired behavior, it seems
reasonable to disallow this.  Such a safeguard would, however,
violate the current specification.

Action:

Either extend the exceptions for . and .. on the noted lines
to list / as well, or specify that the behavior of rm if an
operand resolves to / is undefined.
Run Code Online (Sandbox Code Playgroud)

GNU在此 2003-11-09 提交中rm添加--preserve-root--no-preserve-root选项,但仅在此 2006-09-03 提交中成为默认值,因此在 coreutils 6.2--preserve-root

FreeBSD自2004-10-04 提交以来一直保留斜线(带有“找出我的内衣真的是如何防火的”提交日志),但最初不是在 下,直到十年后他们记得检查 POSIX 现在强制它在这一点上也是在 POSIX 模式下完成的POSIXLY_CORRECT

FreeBSD 的初始提交提到 Solaris 那时已经在这样做了。

@JdePB(在下面的评论中)发现了一个 Sun 内幕故事的链接,证实并提供了有关 Solaris 起源的更多细节,并暗示 Solaris 在向 Austin 小组提出请求之前已经采取了安全措施。

它解释了添加该排除项的理由。虽然如果他们这样做了只能责怪自己rm -rf /,但在一种情况下,如果rm -rf -- "$1/$2"不检查$1/$2是否提供,脚本可以做到这一点,这是错误应用 Solaris 补丁时对某些 Sun 客户造成不良影响的事情(根据该链接)。

禁止删除...早在此之前就已添加,以防止潜在的事故。rm仍然是一个危险的命令。它做它应该做的事情:删除你告诉它的东西。

rm -rf /*
cd /tmp &&  rm -rf .*/   # on some systems where rm -rf ../ still removes
                         # the content of ../ and shells that still
                         # may include . and .. in glob expansions.
rm -rf -- "$diretcory"/* # note the misspelled variable name
dir='foo '; rm -rf $dir/*
Run Code Online (Sandbox Code Playgroud)

也会删除所有内容。众所周知,Shell 文件名补全会在您执行此操作时导致此类问题

rm -rf someth<Tab>/*
Run Code Online (Sandbox Code Playgroud)

扩展为:

rm -rf something /*
Run Code Online (Sandbox Code Playgroud)

因为something碰巧不是目录。

在尝试使用通配符(不是默认情况下)进行调用时,Shell 喜欢tcshzsh会添加额外的提示。rm*tcsh

  • [Bryan Cantrill 讲述了一个关于此的故事。](https://news.ycombinator.com/item?id=8896812) 另见 https://superuser.com/questions/742334/ 和 https://superuser.com/问题/542978/。 (11认同)