I use BSD and Linux every day, I have never had a circumstance which I must use rmdir(1) rather than rm(1). What's the purpose of rmdir's existence?
4 Answers
The main reason is probably historical. Back in the old, old days, there were no rmdir(2)
and mkdir(2)
system calls (we're discussing 7th Edition UNIX™ here), and rmdir(1)
was (of necessity) a SUID root program that used the unlink(2)
system call to remove directories.
The 7th Edition UNIX manuals are available online at http://cm.bell-labs.com/7thEdMan (last checked 2017-04-23); They are also available at http://plan9.bell-labs.com/7thEdMan (last checked 2017-04-23). There also seems to be at least one alternative source online — http://wolfram.schneider.org/bsd/7thEdManVol2/ — for the articles in Volume 2, with a link to the FreeBSD site for the commands and system calls in Volume 1.
The rm
command (a regular non-SUID program) invoked the rmdir(1)
command to remove empty directories. It could not do so itself; that required root privileges. So, the rmdir(1)
command (see here for its source code in Unix V7) existed to remove empty directories, and the rm
command did not remove empty directories itself.
To use rm
to remove directories, you have to give the -r
option.
There's also a symmetry argument. You need a command mkdir(1)
to create directories; it seems reasonable to have a command rmdir(1)
to undo what mkdir(1)
did. Plus they are (these days) simple exercisors of the the rmdir(2)
and mkdir(2)
system calls — yes, back in 7th Edition UNIX, mkdir(1)
was also a SUID root program, using the mknod(2)
call to create a directory node and the link(2)
call to create the .
and ..
entries in the directory.
-
aha! this all makes sense, great!– Howard GuoMay 29, 2012 at 3:05
-
2Nice. I just checked a copy of 3BSD I have here and there's no documentation for an rmdir syscall there either, and rmdir(1) is still implemented using unlink. May 29, 2012 at 3:10
-
4One major downside of the mknod + link and unlink system was that creating a directory was not an atomic operation, so you could end up with a partially complete directory. There were lots of programs devised to check file systems for the inconsistencies that arose;
fsck(1)
is the one that survived. May 29, 2012 at 3:22 -
@Jonathan, bringing back memories of Xenix on that one. Yuck! Yes, really bad things could happen. May 30, 2012 at 0:40
"rm" does not work on directories. You have to either use rmdir or specify the -r switch for a recursive deletion. The reason is historical: unlink
and rmdir
are separate system calls and have been from the early days of Unix.
-
4A happy side-effect is that you're slightly less likely to accidentally delete a directory when you intend to remove only a file.– Adam LissMay 29, 2012 at 3:01
-
Thank you. I noticed that "rm -r" and "rmdir" have the same amount of key strokes. Does rmdir exist purely for historical reason (.. being compatible with decades old Unix programs)?– Howard GuoMay 29, 2012 at 3:03
-
2Actually, back in the early days of Unix, neither
rmdir(2)
normkdir(2)
existed as a system call; userroot
could use themknod(2)
call to create a directory node and thelink(2)
call to create the.
and..
entries in the directory; androot
could use theunlink(2)
call to remove the directory entries. May 29, 2012 at 3:05
Also rmdir only removes empty directories. If you want to make sure you don't delete any additional files in a directory, rmdir
is more safe than rm -r
(except if you aliased rm such that you always need to confirm what you delete, i.e. alias rm='rm -i'
in ~/.bashrc or whatever you are using).
Also, rmdir
makes it easy to remove empty directories with globbing (wildcard) expressions.
For example, to remove all empty directories in /tmp
without touching any files or directories with contents:
cd /tmp ; rmdir *
-
Consider using
rmdir /tmp/*
. If the/tmp
directory is really big, this might run out of space for arguments a little quicker due to the extra five characters per name, but it doesn't require thecd
moving you around the directory hierarchy. It's also worth consideringrmdir /tmp/* 2>/dev/null
to avoid seeing error messages (there'll typically be a lot, and almost all of them will be irrelevant for that task on hand). Dec 20, 2014 at 8:17