22

有没有更快的方法来删除目录然后简单地提交

rm -r -f *directory*

? 我问这个是因为我们每天的跨平台构建非常庞大(例如每个构建 4GB)。所以一些机器上的硬盘经常用完空间。

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

也许在这些平台上有用于目录删除的“特殊”命令?

粘贴编辑(将我自己的单独答案移到问题中):

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

就像是

mv *directory* /dev/null

会好的。

4

13 回答 13

24

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

如果您的目标是让目录 $dir now为空,您可以重命名它,并稍后从后台/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"
于 2009-11-25T08:31:07.667 回答
20

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

EMPTYDIR=$(mktemp -d)
rsync -r --delete $EMPTYDIR/ dir_to_be_emptied/
于 2012-05-23T06:50:43.520 回答
6

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

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

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

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

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

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

mv /filesys1/overnight /filesys1/trash/overnight

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

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

于 2009-11-25T08:52:49.460 回答
5

rm -r directory通过递归深度优先向下遍历directory,删除文件,并在备份途中删除目录。它必须这样做,因为您不能删除非空目录。

冗长而无聊的细节:每个文件系统对象都由文件系统中的一个 inode 表示,该文件系统具有文件系统范围内的平面 inode 数组。 [1] 如果您只是删除了目录而没有先删除其子级,那么子级将保持分配状态,但没有任何指向它们的指针。(fsck在运行时检查那种东西,因为它代表文件系统损坏。)

[1] 对于每个文件系统来说,这可能并不完全正确,并且可能有一个文件系统按照您描述的方式工作。它可能需要像垃圾收集器这样的东西。但是,我所知道的所有常见对象都像fs对象一样归 inode 所有,而目录是名称/inode 编号对的列表。

于 2009-11-28T23:27:05.263 回答
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

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

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

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
于 2009-11-25T09:50:11.157 回答
2

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

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

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

(这里 mtime +4 表示“任何超过 4 天的文件)

另一种方法是配置您的构建器(如果它允许这样的事情)以用当前构建粉碎先前的构建。

于 2009-11-25T08:28:56.047 回答
2

我也在调查这个。

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

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

find . -exec rm {} \;很好,每 5 秒删除约 750 个文件。正在通过另一个外壳检查 rm 速率。

因此,我改为编写了一个简短的脚本来一次 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
于 2011-09-07T06:38:06.637 回答
2

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

于 2014-03-26T18:45:23.367 回答
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 
于 2014-01-17T17:34:33.777 回答
1

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

https://github.com/mhisoft/rdpro

于 2014-11-22T18:13:12.727 回答
0

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

于 2013-10-13T11:42:22.893 回答
0

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

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

directory_to_delete=/ebs/var/tmp/

挂载 /dev/sdb $directory_to_delete

nohup rsync -avh /ebs/ /ebs2/

于 2014-02-18T18:29:36.710 回答
0

我只是find ./ -delete在文件夹中使用清空,它在大约 10 分钟内删除了 620000 个目录(总大小)100GB。

来源:本站评论https://www.slashroot.in/comment/1286#comment-1286

于 2019-03-13T13:04:05.797 回答