Tags

Recent tweets

How to remove empty directories (rmdir -r?)

Someone asked me to remove all empty directories in a particular path.

Option 1: rm -r

You can remove ALL directories and all files using

rm
-r

You will end up with a nice clean system that way, and a new line on your resumé explaining why you left your job at short notice.DON'T TRY THIS AT WORK!

For that matter, don't try any of these "solutions" until you've tried them somewhere which doesn't leave you wishing you'd never heard of AIX Down Under. Whenever I run any command to remove files or directories, I waste two seconds staring at the Enter key and thinking about it.

If you wipe out your system, your company and your career, remember one thing: it wasn't me who pressed the Enter key.

Option 2: rmdir -p

Remember, the aim is to remove empty directories. Now just as you can create a directory structure using

mkdir -p

you can also clean up a directory structure usingrmdir -p

Let me explain.

As the documentation for the mkdir command explains, the -p flag creates missing intermediate path name directories. For example, instead of creating a directory hierarchy one at a time:

mkdir
/amkdir /a/verymkdir /a/very/longmkdir
/a/very/long/directory # well you get the idea

You can do it with a single command using the -p flag:

mkdir
-p /a/very/long/directory/structure/which/nobody/will/ever/find

(Incidentally, there's a command like this called mkdirhier. It creates the directory hierarchy just like mkdir -p, but it doesn't give you the permissions options which are available with mkdir.)

Well, you can remove the directory structure using rmdir -p:rmdir
-p /a/very/long/directory/structure/which/nobody/will/ever/find

The rmdir command will remove directories in reverse (assuming you have write permissions), so that command is like running:rmdir /a/very/long/directory/structure/which/nobody/will/ever/find # "find" directory removed

rmdir will stop removing directories once it gets to one that is not empty.

This option is pretty good, but it does have one drawback: you need to know the bottom of the directory path before you can remove it. If someone asked to remove all the empty directories under a certain branch of the directory structure, you could

saw off the entire branch (using rm -r); or

find all the empty directories (the dead branches) and just prune them.

If it's the latter, then you need to hunt your way down the very end of the path before you can run a command to clean it up. If you're going to do that, it's probably time to create a script ... or use the find command.

Option 3: find command with rmdir

find . -type d -exec rmdir {} \;

The type -d limits the search to directories, and the rmdir will remove them.

cd /a/veryfind . -type d -exec rmdir {} \;

rmdir: 0653-610 Cannot remove current
directory ..rmdir: 0653-611 Directory ./long is not empty.rmdir:
0653-611 Directory ./long/directory is not empty.find: 0652-081
cannot change directory to </a/very/long/directory/structure>:
: A file or directory in the path name does not exist.

However, as you can see, this crashes on the rocks. I think what's happening here is that the find command is storing a list of directories up front, and then traversring the tree, running rmdir first (which fails for all parent directories, since they're not empty) followed by cd to the sub-directory (which fails for the very last child directory). I'm not sure of this, but I'd be interested in your comments.

So, if we were to hard-code this in script form, it would look something like this:directory_list=". ./long ./long/directory ./long/directory/structure"for eachdir in $(echo $directory_list)do rmdir $eachdircd $eachdirdone

The rmdir fails most of the time with the error:rmdir: 0653-611 Directory [directory name] is not empty

and then does the cd

It gets to remove the bottom directory, since it is empty, and then attempts to cd into it, which produces the error:

find: 0652-081
cannot change directory to </a/very/long/directory/structure>:
: A file or directory in the path name does not exist.

Option 4: find command with -depth and rmdir

Fortunately, the find command has an option which lets you cd first, and then do the -exec rmdir. In other words, it goes from the bottom of the directory hierarchy and then heads up the tree. The option is -depth, which as the find command documentation explains:

-depth Always evaluates to the value True. Causes the descent of the directory hierarchy to be done so that all entries in a directory are affected before the directory itself is affected.