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

Ahm*_*kan 4 scripting rm

我正在使用 macOS 和rmGNU coreutils 的工具(不是 macOS\xe2\x80\x99s 自己的rm)。

\n\n

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

\n\n
if [ -d "${cleanup_repo_clone_root}" ]; then\n    echo "Cleaning up tmp directory: ${cleanup_repo_clone_root}"\n    set -x; rm -rf -- "${cleanup_repo_clone_root}"\nfi\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

它向我显示输出:

\n\n
+ set -x\n+ rm -rf -- /var/folders/h7/n46zg3md4l57vzsgxcs355/T/tmp.eizQw1iNBQ\nrm: cannot remove \'/var/folders/h7/n46zg3md4l57vzsgxcs355/T/tmp.eizQw1iNBQ\': Directory not empty\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
$ rm -rf -- /var/folders/h7/n46zg3md4l57vzsgxcs355/T/tmp.eizQw1iNBQ\n
Run Code Online (Sandbox Code Playgroud)\n\n

这里发生了什么?

\n

Chr*_*own 7

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

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

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

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

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

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