有没有比“rm -rf”更快的删除目录的方法?

有没有比“rm -rf”更快的删除目录的方法?

我有一个包含许多文件的文件夹,“rm -rf”需要很长时间才能完成。有没有更快的方法来删除目录及其内容(子目录等)?

答案1

您可以尝试取消链接目录的 inode,但这会留下一大堆孤立文件,fsck 将要 翻雜。

rm尽善尽美。


一些人提到了某些极端情况,即某些东西比其他东西更快。但让我们确保比较的是同一事物的最佳版本。

如果您想删除目录及其中的所有内容,我建议您:

rm -rf path/to/directory

rm将要内部列出要删除的文件和目录。这些都在编译好的C。正是这两个原因让它变得最快。

rm -rf path/to/directory/*这与扩张在 shell 级别并将大量参数传递给rm。然后rm必须解析这些参数,然后从每个参数中递归。这要慢得多。

就像比较的“基准”一样find path/to/directory -exec {} \;毫无意义。它对rm找到的每个文件运行一次。太慢了。Find 可以使用 xargs 样式的构建命令参数,-exec rm {} +但这与扩展一样慢。您可以调用它,它使用对内核的-delete内部调用(就像这样做一样),但这最初仅适用于文件。unlinkrm

重复一遍,除非你把圆盘扔进液态的热岩浆里,rm是国王


需要注意的是,不同的文件系统删除文件的速度不同,因为它们的结构不同。如果您经常这样做,您可能希望将这些文件存储在 XFS 格式的分区中,这样可以非常快速地处理删除操作。

或者使用更快的磁盘。如果您有大量 RAM,使用/dev/shm(RAM 磁盘)可能是一个好主意。

答案2

如果您不需要可用空间,最快的方法是延迟删除并在后台执行:

  • mkdir .delete_me
  • mv 我想要删除的大目录 .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 中的回显之前,请检查您的输出!
  • .delete_me 目录必须位于同一个文件系统中 - 以防每个人都注意到。

更新:我发现了一个并行运行多个 rm 的巧妙技巧 - 如果你有一个大型磁盘阵列,这将会有所帮助:

ionice -c 3 nice find target_directory -depth -maxdepth 3 | xargs -d \n -P 5 -n 5 rm -rf
  • -depth 进行深度优先遍历。

  • -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

答案3

有时,find $DIR_TO_DELETE -type f -delete比更快rm -rf

您可能还想尝试一下mkdir /tmp/empty && rsync -r --delete /tmp/empty/ $DIR_TO_DELETE

最后,如果您需要删除整个分区的内容,最快的方法可能是umountmkfs然后重新mount

答案4

虽然如果你想清除现有目录,这种方法没什么用,但我想说的是,如果你知道你将有一个包含大量文件的目录,而你需要定期清除这些文件,那么一个可能的策略就是将该目录放在它自己的文件系统上(例如,分区)。然后,当您需要清除它时,请卸载它,运行mkfs,然后重新安装它。例如OpenBSD 建议这样做/usr/obj,在系统构建期间会创建许多文件,这些文件必须在下次构建之前删除。

相关内容