The latest (as of 2013) version of the POSIX spec for the
rm utility is here (and the previous one there) and forbids the deletion of
If either of the files dot or dot-dot are specified as the basename portion of an operand (that is, the final pathname component) or if an operand resolves to the root directory, rm shall write a diagnostic message to standard error and do nothing more with such operands.
(as noted by jlliagre, the part about
/ is an addition in SUSv4). The oldest publicly available Unix spec that I could find (XPF4 CAE rev2 (1994)), already specified that
.. can't be removed, though comments in the GNU fileutils changelog suggest it was already the case in older POSIX specs.
-r option to
rm was added in Unix V3 (1973) though it was only deleting the content of the directories, you'd still need to use
rmdir to remove directories.
That changed in Unix V7 (1979, the release that also introduced the Bourne shell and from which most Unices derive).
rm -r now removed directories as well and would not delete the
.. directory tree. The man page states:
It is forbidden to remove the file
.. merely to avoid the antisocial consequences of inadvertently doing something like
rm -r .*.
(though one might argue that
rm -r .* is still antisocial as it deletes everything because
. is included).
It still did accept to remove
. though it would not unlink the
.. entries. So then,
rm -r . was an effective way to empty the current directory.
It's interesting to see that that was already to workaround the bug/misfeature by which globs could include
.. in their expansion. That was fixed in the Forsyth shell (the basis for the original Minix shell and pdksh) in the late 80s,
zsh (1990) and
fish (2005) but not other shells and in particular not the POSIX
sh language that requires the expansion of
.* to include
bash addresses the problem partly only with
shopt -s dotglob where globs (except the
.xxx ones) don't include
.., and with
ksh, you can fix it by doing
When exactly forbidding
. as well was added is not always clear and varies with each Unix. A few findings below.
The forbidding of
. was added sometime between 2.9BSD (1983) and 2.10BSD (1987) and between 4.2BSD (1983) and 4.3BSD (1986).
$ 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");
I don't have much information as neither source or binary are publicly available for the AT&T Unix derivatives after V7. In its online manual, HPUX (based on System III) still mentions that it only forbids
.. while effectively it forbids both which is an indication that probably at least SysIII didn't forbid deletion of
All other online manuals I've checked mention deleting
.. is forbidden which is to be expected to be POSIX conformant.
The early changelog for the GNU fileutils has all the historical information.
While originally neither deleting
.. were forbidden,
.. was forbidden first and then both, all between 1990 and 1991.
As we saw, in
zsh, the expansion of
.* (or any glob) never includes
.. (even in
sh emulation mode). The
rm builtin (which you get if you
zmodload zsh/files) therefore does not treat
.. specially. So, with that
zsh builtin, you can
rm -rf . or
rm -rf .. to empty
rm -rf .* will not remove
rm, the forbidding of deletion of
.. was added in 0.52 (2001)