4

I'm using macOS with rm tool from GNU coreutils (not macOS’s own rm).

So I have a script where I clean up some directory like this:

if [ -d "${cleanup_repo_clone_root}" ]; then
    echo "Cleaning up tmp directory: ${cleanup_repo_clone_root}"
    set -x; rm -rf -- "${cleanup_repo_clone_root}"
fi

I threw a set -x in there to see what's happening.

It's showing me output:

+ set -x
+ rm -rf -- /var/folders/h7/n46zg3md4l57vzsgxcs355/T/tmp.eizQw1iNBQ
rm: cannot remove '/var/folders/h7/n46zg3md4l57vzsgxcs355/T/tmp.eizQw1iNBQ': Directory not empty

but if I copy paste that rm command and execute it, it works fine!

$ rm -rf -- /var/folders/h7/n46zg3md4l57vzsgxcs355/T/tmp.eizQw1iNBQ

What is happening here?

2 Answers2

7

rm's actions when operating on multiple files or directories are not atomic. This matters in this case because rm -r does a bottom-up search for files and directories, removing them from the leaves to the root of the path requested. It does this by unlinking and rmdiring until nothing is left, and then rmdirs the final directory.

These things happen in sequence, so if more files are created before an rmdir is issued, you get back ENOTEMPTY ("Directory not empty").

More than likely your script or another process running on the system is creating things simultaneously with the rm -rf. You may need to think about:

  1. Doing this synchronously instead of asynchronously, or
  2. Retry rm -rf if it fails and returns ENOTEMPTY (although then the other application may fail since the directory was removed from below it)

You can find the other application that's creating files using something like fanotify or an eBPF script, like opensnoop from BCC. inotify may also be helpful, but it sadly doesn't include the process creating files in its output.

Another possibility is that removing a file failed, but this may be masked by -f. Try running without -f to see what the error might be in that case.

Chris Down
  • 125,559
  • 25
  • 270
  • 266
2

It turns out an earlier open $dir call I was making was launching one of the subdirectories of the directory I want to remove on macOS Finder (file browser desktop app).

It looks like macOS is giving this cryptic Directory not empty (ENOEMPTY) error if there's a process putting a lock on one of the files/dirs in that directory you want to remove.