1

For testing purposes, I created the following directories.

user@linux:~$ mkdir dir0{1..3}

user@linux:~$ ls -l
total 12K
drwxr-xr-x 2 user user 4.0K Mei  31 10:45 dir01
drwxr-xr-x 2 user user 4.0K Mei  31 10:45 dir02
drwxr-xr-x 2 user user 4.0K Mei  31 10:45 dir03
user@linux:~$ 

Then, I removed it with find -exec

user@linux:~$ find -type d -exec rmdir {} \;
rmdir: failed to remove '.': Invalid argument
find: ‘./dir02’: No such file or directory
find: ‘./dir01’: No such file or directory
find: ‘./dir03’: No such file or directory
user@linux:~$ 

The directories were removed, I verified it.

user@linux:~$ ls -l
total 0
user@linux:~$ 

My questions are:

1) I don't understand why does the messages were there. Any idea why?

rmdir: failed to remove '.': Invalid argument
find: ‘./dir02’: No such file or directory

I don't see this kind of error with rmdir

user@linux:~$ mkdir dir0{1..3}
user@linux:~$ 

user@linux:~$ ls -l
total 12K
drwxr-xr-x 2 user user 4.0K Mei  31 22:58 dir01
drwxr-xr-x 2 user user 4.0K Mei  31 22:58 dir02
drwxr-xr-x 2 user user 4.0K Mei  31 22:58 dir03
user@linux:~$ 

user@linux:~$ rmdir *
user@linux:~$ 

user@linux:~$ ls -l
total 0
user@linux:~$ 

2) Is it possible to remove these messages?

1

What presumably happens is that, with the -exec ... \; construct, find does its work step by step:

  • walk the directory tree, finding entries that match -type d, and
  • run rmdir on such entries as soon as they are found.

This means that, in your example, find will look at dir01, keep it in mind as a directory to enter later, then run rmdir on it, and then, when trying to recurse into dir01, fail because it does not exist anymore.

Running with -exec rmdir {} + should help in this instance: a single call to rmdir dir01 dir02 dir03 will be emitted. This gets rid of the last three error messages.

The error message about . is because, well, ., the current directory is indeed a directory, but not one that rmdir can delete, because it is not empty. Use -min-depth to stop considering it, making the command:

find -mindepth 1 -type d -exec rmdir {} +

This is not perfect; nested directories or a large number of matching directories could still cause error messages to be printed, but this should work in the simple case from the question.

| improve this answer | |
2

You get those "No such file or directory" errors from find because find is trying to enter directories that it has just removed. It will by default apply its actions to all matching things in the directory that it's currently visiting before continuing into the subdirectories.

Add -depth to the invocation of find to make find do a depth-first search of its search paths, which in turn means that if you execute rmdir on a directory, it will already have visited it and won't try to visit it again.

The -depth option is implied when using -delete for this reason (in implementations of find that has -delete).

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

-depth is a standard option for the find utility.

Note that rmdir only works on empty directories. If you have lots of non-empty directories, the above command would produce lots of error messages.

Instead, if your find supports it, use -empty:

find . -type d -empty -delete

This would delete empty directories.

With a find that does not have the non-standard -delete nor -emtpy:

find . -depth -type d -exec sh -c '
    for dirpath do
        set -- "$dirpath"/*
        [ ! -e "$1" ] && rmdir "$dirpath"
    done' sh {} +

This would test whether the found directories were empty, and if they were, they would be deleted.

That's a long piece of code to avoid seeing some error messages due to directories being non-empty, but any error messages that are produced will hopefully be more interesting to look at as they would probably be "permission denied" errors. Redirecting the errors to /dev/null in the first find command at the top would have hidden such errors.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.