在POSIX规范的最新(2017年)版的rm
效用是在这里(和前一个有),禁止删除.
和..
。
如果将点或点文件中的任何一个指定为操作数的基本名称部分(即最终路径名组件),或者如果操作数解析为根目录,则rm应将诊断消息写入标准错误,并且不执行任何操作这类操作数更多。
如@jlliagre所指出的,关于的部分/
是SUSv4中的一个附加项。
最古老的公共可用规范的Unix,我能找到(XPF4 CAE转2(1994)),已指定了.
和..
不能被删除,但在GNU fileutils中的changelog言论表明它已经在旧的POSIX规范的情况。
请注意,它也适用于dir/..
和../
,但是某些实现(包括UNIX认证的Solaris 11和macOS)仍然不能防范rm -rf ../
或rm -rf .*/
)。
历史
早期的大学
将-r
要选择rm
在Unix的V3(1973)加入虽然它只是删除目录的内容,你仍旧需要使用rmdir
,删除目录。
这种情况在Unix V7中有所改变(1979年,该版本还引入了Bourne shell,并且大多数Unices都源自此版本)。rm -r
现在也删除了目录,并且不会删除..
目录树。该手册页指出:
禁止删除该文件..
只是为了避免因疏忽而执行类似操作的反社会后果rm -r .*
。
(尽管有人可能会认为这rm -r .*
仍然是反社会的,因为它删除了所有内容,因为.
包含了所有内容)。
.
尽管它不会取消链接.
或..
条目,但仍接受删除。因此,这rm -r .
是清空当前目录的有效方法。
另请注意,该保护措施仅适用于字面量..
,而不适用于dir/..
或./..
。因此,rm -rf ./.*
仍将递归删除父目录中的所有内容。
有趣的是,这已经解决了glob可能包含的错误/功能不全.
以及..
扩展的问题。这是固定的福塞斯壳在80年代末(原来为Minix的外壳和pdksh程序的基础),zsh
(1990)和fish
(2005),而不是其他炮弹,尤其是不POSIX的sh
语言,需要扩大.*
到包括.
和..
若它们由返回readdir()
((bash
仅shopt -s dotglob
在glob(除glob之外.xxx
)不包含.
或的情况下部分解决了问题..
,使用ksh
可以解决此问题FIGNORE='@(.|..)'
))。
何时.
添加确切的禁止并不总是很清楚,并且每个Unix都不同。以下是一些发现。
BSD
禁止.
在2.9BSD(1983)和2.10BSD(1987)之间以及4.2BSD(1983)和4.3BSD(1986)之间添加(请参阅在unix-history-repo中加盖1985年的更改)。
$ wget -qO- http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.9BSD/root.tar.gz |
zgrep -ao 'rm: canno[[:print:]]*'
rm: cannot remove `..'
$ wget -qO- http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.10bsd.tar.gz |
zgrep -ao 'rm: canno[[:print:]]*'
rm: cannot remove `.' or `..'
rm: cannot remove `.' or `..'\n");
对于dir/.
和dir/..
,请参见1988年的更改(BSD 4.3 Net / 1)。
为了这一天,在rm
中的FreeBSD(和MacOS的类似衍生产品)仍然在清空当前或父目录rm -rf ./
或rm -rf ../
虽然(事项rm -rf .*/
)。
系统V
我没有太多信息,因为V7之后的AT&T Unix派生文件都没有公开可用的源代码或二进制文件。在其在线手册中,HPUX(基于System III)仍然提到它仅禁止..
而有效地禁止两者,这表明至少SysIII可能不禁止删除.
(编辑:现在查看SysIII rm
源代码,它是自Unix V7起几乎没有变化)。
我检查过的所有其他在线手册都提到删除.
或被..
禁止符合POSIX标准。
的Solaris rm
时仍然清空当前或父目录rm -rf ./
或rm -rf ../
。
GNU
GNU fileutils的早期changelog具有所有历史信息。
虽然最初既不删除.
也不..
禁止,但在1990年至1991年之间..
都先禁止再删除(包括dir/.
)。
其他
如我们所见,在中zsh
,.*
(或任何全局)的扩展从不包含.
或..
(即使在sh
仿真模式下)。因此,rm
内置zmodload zsh/files
函数(如果得到的话)将不被对待.
或..
特别对待。因此,使用该zsh
内置函数,您可以rm -rf .
或rm -rf ..
清空.
或..
,但rm -rf .*
不会删除.
或..
。
在busybox中rm
,禁止删除.
和..
在0.52(2001)中添加
rm
,但我认为这是值得一提的,你仍然可以有意想不到的效果chmod
,chown
等匹配时.*
。