Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

The expression .* is expanded by bash to include the current and parent directories:

$ ls -la
total 2600
drwxrwxrwx   2 terdon terdon 2162688 Sep 10 16:22 .
drwxr-xr-x 142 terdon terdon  491520 Sep 10 15:34 ..
-rw-r--r--   1 terdon terdon       0 Sep 10 16:22 foo
$ echo .*
. ..

If I run rm -rf .* on my Debian using GNU bash, version 4.2.36(1)-release and rm from rm (GNU coreutils) 8.13, I get this message:

$ rm -rf .*
rm: cannot remove directory: `.'
rm: cannot remove directory: `..'

Is this a GNU thing or is it POSIX? Are there any *nix systems where the command above will silently delete . and ..?

Also, is this a safety feature of the shell or of the rm command itself?

share|improve this question
1  
I know this question is in the context of rm, but I thought it was worth mentioning that you can still have unexpected results with chmod,chown,etc when matching .*. –  Aaron Copley Sep 10 '13 at 17:46

1 Answer 1

up vote 28 down vote accepted

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 . and ...

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 . and .. can't be removed, though comments in the GNU fileutils changelog suggest it was already the case in older POSIX specs.

history

Early unices

The -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 . or .. 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 . and .. in their expansion. We had to wait for zsh (1990) to have a shell where that bug was fixed (it's also fixed in fish (2005)). (bash addresses the problem partly only with shopt -s dotglob where globs (except the .xxx ones) don't include . or .., and with ksh, you can fix it by doing FIGNORE='@(.|..)').

When exactly forbidding . as well was added is not always clear and varies with each Unix. A few findings below.

BSDs

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");

System V

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 . or .. is forbidden which is to be expected to be POSIX conformant.

GNU

The early changelog for the GNU fileutils has all the historical information.

While originally neither deleting . or .. were forbidden, .. was forbidden first and then both, all between 1990 and 1991.

other

As we saw, in zsh, the expansion of .* (or any glob) never includes . or .. (even in sh emulation mode). The rm builtin (which you get if you zmodload zsh/files) therefore does not treat . or .. specially. So, with that zsh builtin, you can rm -rf . or rm -rf .. to empty . or .., but rm -rf .* will not remove . or ...

In busybox rm, the forbidding of deletion of . and .. was added in 0.52 (2001)

share|improve this answer
    
Odd, that seems to specify that rm -rf . / (note the space) should print two warnings (for . and /) and exit, but we seem to get a question asking how to recover from that every couple months. –  Kevin Sep 10 '13 at 16:00
6  
@Kevin Not all systems are POSIX compliant and the root directory restriction was only explicitly added in the latest POSIX release. –  jlliagre Sep 10 '13 at 16:15
    
@jlliagre I see. GNU generally tries to implement POSIX (+extensions, of course), and I'd imagine they'd want to put this one in, but if it's fairly new that would explain it. –  Kevin Sep 10 '13 at 16:23
2  
@Stephane: you're right, but I'd still add a big "Yes, it could happen! But ..." at the beginning of your answer, so that people undoubtedly know that indeed, on some (older or just non-POSIX compliant) systems, they could delete parent directories. I try to always point out those possibility (ie, I try to stay on the safe side, even if it makes the answer sometimes harder to read/remember) ^^ –  Olivier Dulac Sep 10 '13 at 17:49
1  
@MartinSchröder, On BSDs, it was added somewhere between 2.8BSD and 2.10BSD (before only ".." was forbidden like in UnixV7) and between 3BSD and 4.3RENO. On SysV systems, it's less clear. HPUX manual for instance claims it only forbid ".." but in effect it forbids both "." and "..", it's only the manual that is not up to date. –  Stéphane Chazelas Sep 11 '13 at 12:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.