Unix:快速'删除目录'以清理每日构建

时间:2009-11-25 08:06:00

标签: build solaris aix

是否有更快的方法来删除目录,然后只需提交

rm -r -f *directory*

?我问这个是因为我们的日常跨平台构建非常庞大(例如每个构建4GB)。因此,某些机器上的硬盘经常耗尽空间。

这就是我们的AIX和Solaris平台的情况。

也许在这些平台上有删除目录的'特殊'命令?

PASTE-EDIT(将我自己单独的答案移到问题中):

我一般想知道为什么'rm -r -f'这么慢。不'rm'只需要修改'..'或'。'用于取消分配文件系统条目的文件。

类似

mv *directory* /dev/null

会很好。

13 个答案:

答案 0 :(得分:23)

要从文件系统中删除目录,rm是您最快的选择。 在linux上,有时我们在ramdisk中进行构建(几GB),它有一个非常令人印象深刻的删除速度:)你也可以尝试不同的文件系统,但在AIX / Solaris上你可能没有很多选项......

如果你的目标是让目录$ dir为空现在,你可以重命名它,稍后从后台/ cron作业中删除它:

mv "$dir" "$dir.old"
mkdir "$dir"
# later
rm -r -f "$dir.old"

另一个技巧是为$ dir创建一个单独的文件系统,当你想删除它时,你只需重新创建文件系统。像这样:

# initialization
mkfs.something /dev/device
mount /dev/device "$dir"


# when you want to delete it:
umount "$dir"
# re-init
mkfs.something /dev/device
mount /dev/device "$dir"

答案 1 :(得分:17)

我忘记了这个技巧的来源,但它确实有效:

EMPTYDIR=$(mktemp -d)
rsync -r --delete $EMPTYDIR/ dir_to_be_emptied/

答案 2 :(得分:5)

至少在AIX上,您应该使用逻辑卷管理器LVM。我们所有的系统都将所有物理硬盘驱动器捆绑到一个卷组中,然后创建一个大的honkin'文件系统。

这样,您可以随意添加物理设备到您的计算机,并将文件系统的大小增加到您需要的任何位置。

我见过的另一个解决方案是在每个文件系统上分配一个垃圾目录,并使用mvfind cron作业的组合来解决空间问题。< / p>

基本上,每隔十分钟运行一次cron作业并执行:

rm -rf /trash/*
rm -rf /filesys1/trash/*
rm -rf /filesys2/trash/*

然后,当您希望回收该文件系统上的特定目录时,请使用以下内容:

mv /filesys1/overnight /filesys1/trash/overnight

并且,在接下来的十分钟内,您的磁盘空间将开始恢复。即使在删除已删除的版本之前,filesys1/overnight目录也可立即使用。

垃圾目录与您想要删除的目录位于同一文件系统上非常重要,否则您手上会进行大量的复制/删除操作,而不是相对快速的移动。

答案 3 :(得分:3)

如果rm -rf速度很慢,也许您正在使用“同步”选项或类似选项,它会过于频繁地写入磁盘。在具有普通选项的Linux ext3上,rm -rf非常快。

快速删除的一个选项可以在Linux上运行,也可能在各种Unixen上运行,就是使用循环设备,例如:

hole temp.img $[5*1024*1024*1024]  # create a 5Gb "hole" file
mkfs.ext3 temp.img
mkdir -p mnt-temp
sudo mount temp.img mnt-temp -o loop

“漏洞”程序是我自己创建的一个程序,用于创建一个大的空文件,使用“漏洞”而不是磁盘上分配的块,这要快得多,并且在您真正需要之前不会使用任何磁盘空间。 http://sam.nipl.net/coding/c-examples/hole.c

我刚注意到GNU coreutils包含一个类似的程序“truncate”,所以如果你有,你可以用它来创建图像:

truncate --size=$[5*1024*1024*1024] temp.img

现在,您可以使用mnt-temp下的挂载映像进行临时存储,以进行构建。完成后,执行此操作将其删除:

sudo umount mnt-temp
rm test.img
rmdir mnt-temp

我认为您会发现删除单个大文件比删除大量小文件要快得多!

如果你不打算编译我的“hole.c”程序,你可以使用dd,但速度要慢得多:

dd if=/dev/zero of=temp.img bs=1024 count=$[5*1024*1024]  # create a 5Gb allocated file

答案 4 :(得分:3)

rm -r directory的工作原理是通过目录递归深度优先,删除文件,并在备份的路上删除目录。它必须,因为您无法删除非空的目录。

冗长乏味的细节:每个文件系统对象都由文件系统中的inode表示,该文件系统具有文件系统范围的平面inode数组。[1]如果你刚刚删除目录而没有先删除它的子节点,那么子节点将保持分配状态,但没有任何指针。 (fsck在运行时检查此类事物,因为它表示文件系统损坏。)

[1]对于那里的每个文件系统而言,这可能并不严格,并且可能有一个文件系统按照您描述的方式工作。它可能需要类似垃圾收集器的东西。但是,我所知道的所有常见的 act 就像fs对象一样,都是由inode拥有的,而目录是名称/ inode编号对的列表。

答案 5 :(得分:2)

我认为实际上除了“rm -rf”之外别无他法,因为你引用了删除你的目录。

为了避免一遍又一遍地手动执行,你可以每天cron一个脚本,如果它们“足够老”,可以递归删除构建根目录的所有构建目录,如下所示:

find <buildRootDir>/* -prune -mtime +4 -exec rm -rf {} \;

(此处mtime +4表示“任何超过4天的文件”)

另一种方法是配置你的构建器(如果它允许这样的东西)用当前的构建器粉碎上一个构建。

答案 6 :(得分:2)

我也在研究这个问题。

我有一个拥有600,000多个文件的目录。

rm *会失败,因为条目太多了。

find . -exec rm {} \;很不错,每5秒删除约750个文件。是通过另一个shell检查rm率。

所以,我写了一个简短的脚本来同时发送许多文件。每5秒获得约1000个文件。我们的想法是尽可能多地将文件放入1 rm命令中以提高效率。

#!/usr/bin/ksh
string="";
count=0;
for i in $(cat filelist);do
    string="$string $i";
    count=$(($count + 1));
  if [[ $count -eq 40 ]];then
    count=1;
    rm $string
    string="";
  fi
done

答案 7 :(得分:2)

使用 perl -e&#39; for(&lt; *&gt;){((stat)[9]&lt;(unlink))}&#39; 请参考以下链接: http://www.slashroot.in/which-is-the-fastest-method-to-delete-files-in-linux

答案 8 :(得分:1)

在Solaris上,这是我找到的最快的方法。

find /dir/to/clean -type f|xargs rm

如果您有包含奇数路径的文件,请使用

find /dir/to/clean -type f|while read line; do echo "$line";done|xargs rm 

答案 9 :(得分:0)

我不得不在Windows中删除超过3,00,000个文件。我安装了cygwin。幸运的是,我拥有数据库中的所有主目录。创建一个for循环并基于行输入和使用rm -rf删除

答案 10 :(得分:0)

在将剩余部分复制到新的200 GB XFS卷之前,需要从AWS EBS 1 TB磁盘(ext3)上的数十个目录中删除700 GB。花费数小时将该体积保持在100%wa。由于磁盘IO和服务器时间不是免费的,因此每个目录只需要几分之一秒。

其中/ dev / sdb 是任何大小的空卷

directory_to_delete = / EBS / var / tmp中/

mount / dev / sdb $ directory_to_delete

nohup rsync -avh / ebs / / ebs2 /

答案 11 :(得分:0)

我编写了一个比rm更快的小型Java应用程序RdPro(递归目录清除工具)。它还可以删除用户在Linux / Unix和Windows的root.Works下指定的目标目录。它有命令行版本和GUI版本。

https://github.com/mhisoft/rdpro

答案 12 :(得分:0)

我只使用文件夹中的 ImageView imageView = new ImageView(this); imageView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); imageView.setScaleType(ImageView.ScaleType.CENTER); GlideApp.with(this) .load(url) .skipMemoryCache(true) .fitCenter() .onlyRetrieveFromCache(true) .into(imageView); frameLayout.addView(imageView); 清空,并且在10分钟内删除了620000个目录(总大小)100GB。

来源:此网站https://www.slashroot.in/comment/1286#comment-1286

中的评论