2015-03-20
Unix's mistake with rm
and directories
Welcome to Unix, land of:
; rm thing rm: cannot remove 'thing': Is a directory ; rmdir thing ;
(And also rm
may only be telling you half the story, because
you can have your rmdir
fail with 'rmdir: failed to remove
'thing': Directory not empty
'. Gee thanks both of you.)
Let me be blunt here: this is Unix exercising robot logic. Unix knows
perfectly well what you want to do, it's perfectly safe to do so, and
yet Unix refuses to do it (or tell you the full problem) because you
didn't use the right command. Rm will even remove directories if you
just tell it 'rm -r thing
', although this is more dangerous than
rmdir
.
Once upon a time rm
had almost
no choice but to do this because removing directories took special
magic and special permissions (as '.
' and '..
' and the directory
tree were maintained in user space). Those days are long over, and
with them all of the logic that would have justified keeping this
rm
(mis)feature. It lingers on only as another piece of Unix
fossilization.
(This restriction is not even truly Unixy; per Norman Wilson, Research Unix's 8th edition removed the restriction, so the very heart of Unix fixed this. Sadly very little from Research Unix V8, V9, and V10 ever made it out into the world.)
PS: Some people will now say that the Single Unix Specification
(and POSIX) does not permit rm
to behave this way. My view is
'nuts to the SUS on this'. Many parts of real Unixes are already
not strictly POSIX compliant, so if you really have to have this
you can add code to rm
to behave in a strictly POSIX compliant
mode if some environment variable is set. (This leads into another
rant.)
(I will reluctantly concede that having unlink(2)
still fail on
directories instead of turning into rmdir(2)
is probably safest,
even if I don't entirely like it either. Some program is probably
counting on the behavior and there's not too much reason to change
it. Rm is different in part because it is used by people; unlink(2)
is not directly. Yes, I'm waving my hands a bit.)