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
最好重新构建这个东西,这样就没有必要了。