Unix's mistake with rm and directories

March 20, 2015

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


Comments on this page:

With GNU rm,

   alias rm="rm -d"
By Ewen McNeill at 2015-03-31 16:13:09:

It would also appear that, eg, OpenBSD rm understands rm -d, as does OS X (at least as of 10.9). Interestingly I'd not noticed that before, but Wikipedia states it has been there since 4.4BSD-Lite2. Presumably it was added to GNU rm to match (latter link from the Wikipedia page; Savannah change from 2012).

It doesn't look like the GNU rm on most of my Linux systems is new enough to make it worth trying to retrain my fingers yet... but maybe in a year or two.

Ewen

Written on 20 March 2015.
« A brief history of fiddling with Unix directories
Spammers show up fast when you open up port 25 (at least sometimes) »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Fri Mar 20 00:41:36 2015
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.