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.

In an old version of Unix, the rm command would delete directories if they were empty. From the Research Unix Eighth Edition man page for rm: "If an entry is a directory it is removed only if empty." I like this behaviour, so I've got this alias in my /etc/profile: alias rm='rm -d' I'm using the GNU coreutils version of rm, in which -d tells rm to go ahead and remove directories if they're empty.

So far so good. This alias allows me to use rm like the old days. However, I'd like to take it a step further. I'd like rm to delete a directory even if the directory contains other directories, so long as directories are the only thing there. It doesn't matter how deep the directory structure goes, as long as there aren't any files in there, just empty (once you get to the bottom) directories, I'd like rm to remove them all.

Could this be written as an alias which would still function as the regular rm and delete any files passed to it?

share|improve this question
    
How about rmdir -p? –  Kevin Dec 9 '13 at 0:45
    
Thanks for the suggestion Kevin, but this isn't quite the behaviour I'm looking for. If I run mkdir -p a/b1/c2 && mkdir -p a/b2/c2; rmdir -p a/b1/c1;, I'm still left with a, a/b2, and a/b2/c2. What I'd like is to pass just the top level (a in this case) to rm, and have everything below it removed. –  WhiteHotLoveTiger Dec 9 '13 at 0:57
add comment

1 Answer

up vote 5 down vote accepted

You want to traverse a directory tree and see if it contains anything other than a directory. This is beyond rm's capabilities. You need other tools such as find. You can delete the empty directories under a given directory this way (-depth causes parent directories that become empty to be deleted as well):

find "$x" -depth -type d -exec rmdir {} +

Here is a function which, for each argument, deletes the argument if it is a non-directory file or a directory tree not containing anything other than directories. Note that this function isn't atomic: if one of the arguments changes while it's running, you may end up with an error message, but it's safe in that it won't delete any non-directory inside a directory passed as argument.

rm () {
  ret=0
  for x; do
    case $x in -*) x=./$x;; esac
    if [ -d "$x" ]; then
      if [ -n "$(find "$x" ! -type d | head -n 1)" ]; then
        echo 1>&2 "$x: non-empty directory tree"
        ret=2
      else
        find "$x" -depth -exec rmdir {} +
        if [ -d "$x" ]; then ret=2; fi
      fi
    else
      command rm "$x" || [ $ret -gt 1 ] || ret=2
    fi
  done
  return $ret
}
share|improve this answer
add comment

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.