问题描述
我有一个文件夹,里面有很多文件,“rm -rf”需要很长时间才能完成。有没有更快的方法来删除目录及其内容(子目录等)?
最佳办法
您可以尝试取消目录的 inode 链接,但这会给您留下大量孤立文件,fsck
会抛出这些文件。
rm
已经够用了。
一些人提到了一些事情比其他事情更快的边情况。但是让我们确保我们正在比较相同事物的最佳版本。
如果您想删除目录及其中的所有内容,我建议您:
rm -rf path/to/directory
rm
将在内部列出它要删除的文件和目录。这一切都在编译的 C 中。这是它最快的两个原因。
这与 rm -rf path/to/directory/*
非常明显不同,后者将在 shell 级别扩展并将大量参数传递给 rm
。然后 rm
必须解析这些,然后从每个递归。那要慢得多。
就像比较 find path/to/directory -exec {} \;
的 “benchmark” 是无稽之谈。它为找到的每个文件运行一次 rm
。太慢了。 Find can xargs-style 使用 -exec rm {} +
构建命令参数,但这与扩展一样慢。您可以调用 -delete
,它使用对内核的内部 unlink
调用(就像 rm
那样),但这首先只适用于文件。
所以重复一遍,除非你把圆盘扔进炽热的岩浆中,否则 rm
才是王道。
与此相关的是,不同的文件系统由于它们的结构而以不同的速率删除它们。如果您定期执行此操作,您可能希望将这些文件存储在 XFS 格式的分区中,这样可以非常快速地处理删除操作。
或者使用更快的磁盘。如果您有大量 RAM,使用 /dev/shm
(RAM 磁盘)可能是一个想法。
次佳办法
如果您不需要可用空间,最快的方法是延迟删除并在后台执行此操作:
-
mkdir .delete_me
-
mv big-directory-that-i-want-gone .delete_me
然后有一个 crontab 在后台执行它,在一个安静的时间,具有低 I/O 优先级:
3 3 * * * root ionice -c 3 nice find /path/to/.delete_me -maxdepth 1 ! -name \. -exec echo rm -rf "{}" +
笔记:
-
在删除 crontab 中的 echo 之前检查您的输出!
-
.delete_me 目录必须在同一个文件系统中 – 以防每个人都不明显。
更新:我发现了一个并行运行多个 rm 的巧妙技巧 – 如果您有一个大型磁盘阵列,这将有所帮助:
ionice -c 3 nice find target_directory -depth -maxdepth 3 | xargs -d \n -P 5 -n 5 rm -rf
-
-depth 进行 depth-first 遍历。
-
-maxdepth 限制目录遍历的深度,因此我们最终不会监听单个文件。
-
-d \n 处理文件名中的空格。
-
-P 和 -n 处理并行度(查看联机帮助页)。
参考:http://blog.liw.fi/posts/rm-is-too-slow/#comment-3e028c69183a348ee748d904a7474019
更新 2(2018 年):在 Ubuntu 18.04 附带的 ZFS 中,我将它用于所有事情,我将为任何大项目创建一个新数据集。如果您提前计划并提前执行此操作,您可以在完成后简单地 “zfs destroy” 一个文件系统。 😉
我使用 zfsonlinux wiki 中的说明将 Ubuntu 本地安装到 ZFS:https://github.com/zfsonlinux/zfs/wiki/Ubuntu-18.04-Root-on-ZFS
第三种办法
有时, find $DIR_TO_DELETE -type f -delete
比 rm -rf
快。
您可能还想尝试 mkdir /tmp/empty && rsync -r --delete /tmp/empty/ $DIR_TO_DELETE
。
最后,如果您需要删除整个分区的内容,最快的可能是 umount
、 mkfs
和 mount
。