如果并行删除,rm -rf 失败

如果并行删除,rm -rf 失败

rm -rf如果尝试删除同一文件树,则会失败(我认为是因为rm先枚举文件,然后删除)。

一个简单的测试:

# Terminal 1
for i in `seq 1 1000`; do mkdir -p /tmp/dirtest/$i; done

# Now at the same time in terminal 1 and 2
rm -rf /tmp/dirtest

将会有一些输出到 stderr,例如:

...
rm: cannot remove directory `/tmp/dirtest/294': No such file or directory
rm: cannot remove directory `/tmp/dirtest/297': No such file or directory
rm: cannot remove directory `/tmp/dirtest/304': No such file or directory

我可以通过将其重定向到 来忽略所有 stderr 输出/dev/null,但删除/tmp/dirtest实际上会失败!两个命令完成后,/tmp/dirtest仍然存在。

如何rm正确删除目录树并真正忽略所有错误?

答案1

可恶的。但从某种意义上说,当两个并发进程正在操作目录树时,您就是在自找麻烦。 Unix 提供了对单个文件进行原子操作的原语,但不提供对整个目录树的原语。

一个简单的解决方法是让您的脚本在删除目录之前重命名该目录。由于您的用例具有协作脚本,因此新名称可以预测。

mv /build/tree /build/tree.rm.$$
mkdir /build/tree
rm -rf /build/tree.rm.$$

也许您甚至可以rm稍后在构建执行一些 CPU 密集型任务时在后台执行此操作。

答案2

我很好奇构建系统是如何最终变成这样的。你能改变它吗?至少,您可以创建一个标志,让脚本知道另一个脚本已经在完成这项工作......

mkdir /tmp/flag.rmdirtest && rm -rf /tmp/dirtest && rmdir /tmp/flag.rmdirtest

最好重新构建这个东西,这样就没有必要了。

相关内容