为什么我用“rm -rf”得到“目录不为空”?

为什么我用“rm -rf”得到“目录不为空”?

我使用 macOS 和rmGNU coreutils 的工具(不是 macOS 自己的rm)。

所以我有一个脚本来清理一些目录,如下所示:

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

我扔了一个set -x进去看看发生了什么。

它向我显示输出:

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

但如果我复制粘贴该 rm 命令并执行它,它就可以正常工作!

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

这里发生了什么?

答案1

rm操作多个文件或目录时的操作不是原子的。在这种情况下这很重要,因为rm -r会自下而上搜索文件和目录,将它们从所请求路径的叶子到根删除。它通过unlinking 和rmdiring 来完成此操作,直到什么都没有剩下,然后rmdir是最终目录。

这些事情按顺序发生,因此如果在发出之前创建了更多文件rmdir,您会返回ENOTEMPTY(“目录不为空”)。

您的脚本或系统上运行的另一个进程很可能正在与rm -rf.您可能需要考虑:

  1. 同步而不是异步执行此操作,或者
  2. 如果失败并返回 ENOTEMPTY,请重试rm -rf(尽管其他应用程序可能会失败,因为该目录已从其下面删除)

fanotify您可以找到使用类似eBPF 脚本创建文件的其他应用程序,opensnoop例如密件抄送inotify可能也有帮助,但遗憾的是它不包括在其输出中创建文件的过程。

另一种可能性是删除文件失败,但这可能被-f.尝试不运行,-f看看在这种情况下可能会出现什么错误。

答案2

事实证明,open $dir我之前拨打的电话是在 macOS Finder(文件浏览器桌面应用程序)上启动我想要删除的目录的子目录之一。

Directory not empty如果有一个进程锁定了您要删除的目录中的某个文件/目录,那么macOS 似乎会给出此神秘的(ENOEMPTY) 错误。

相关内容