我使用 macOS 和rm
GNU 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
会自下而上搜索文件和目录,将它们从所请求路径的叶子到根删除。它通过unlink
ing 和rmdir
ing 来完成此操作,直到什么都没有剩下,然后rmdir
是最终目录。
这些事情按顺序发生,因此如果在发出之前创建了更多文件rmdir
,您会返回ENOTEMPTY
(“目录不为空”)。
您的脚本或系统上运行的另一个进程很可能正在与rm -rf
.您可能需要考虑:
- 同步而不是异步执行此操作,或者
- 如果失败并返回 ENOTEMPTY,请重试
rm -rf
(尽管其他应用程序可能会失败,因为该目录已从其下面删除)
fanotify
您可以找到使用类似eBPF 脚本创建文件的其他应用程序,opensnoop
例如密件抄送。inotify
可能也有帮助,但遗憾的是它不包括在其输出中创建文件的过程。
另一种可能性是删除文件失败,但这可能被-f
.尝试不运行,-f
看看在这种情况下可能会出现什么错误。
答案2
事实证明,open $dir
我之前拨打的电话是在 macOS Finder(文件浏览器桌面应用程序)上启动我想要删除的目录的子目录之一。
Directory not empty
如果有一个进程锁定了您要删除的目录中的某个文件/目录,那么macOS 似乎会给出此神秘的(ENOEMPTY) 错误。