删除目录中所有文件和子文件夹的最快方法是什么?

Lei*_*Hao 18 linux deleted-files

一个程序创建了许多嵌套的子文件夹。我尝试使用命令 rm -fr *将它们全部删除。但它很慢。我想知道有没有更快的方法将它们全部删除?

Ant*_*hon 22

从该目录中删除它们的最快方法是将它们移出那里,然后在后台删除它们:

mkdir ../.tmp_to_remove
mv -- * ../.tmp_to_remove
rm -rf ../.tmp_to_remove &
Run Code Online (Sandbox Code Playgroud)

这假设您的当前目录不是某个挂载分区的顶层(即../.tmp_to_remove在同一文件系统上)。

--mv(由斯特凡在编辑)是必要的,如果您有从一个任意文件/目录名-

上面会在几分之一秒内从当前目录中删除文件,因为它不必递归处理子目录。从文件系统中实际删除树需要更长的时间,但由于它不在路上,它的实际效率应该没有那么重要。


Rah*_*hul 20

rsync出奇的快速和简单。您必须先创建空目录,

mkdir 空目录
rsync -a --delete emptydir/ yourdirectory/

yourdirectory/ 是要从中删除文件的目录。

  • `rsync` 的有趣用法。它比 rm 快吗? (3认同)
  • @pfnuesel :是的,请参阅此答案 http://serverfault.com/a/328305/105902。 (2认同)

Sté*_*las 9

的一个问题rm -rf *,或更正确的等价物rm -rf -- *是,shell 必须首先列出当前目录中的所有(非隐藏)文件,对它们进行排序并将它们传递给rm,如果当前目录中的文件列表很大,则将增加一些不必要的额外开销,如果文件列表太大,甚至可能会失败。

通常,您会这样做rm -rf .(这也有删除隐藏文件的好处)。但是大多数rm实现,包括所有符合 POSIX 的实现都拒绝这样做。原因是某些 shell(包括所有 POSIX 的)具有这样的错误特征,即.*glob的扩展将包括...。这意味着这rm -rf .*将删除当前和父目录,因此rm已进行修改以解决这些 shell 的错误功能。

一些外壳pdksh(和其他 Forsyth 外壳衍生物)zshfish没有这种错误特征。zsh有一个rm内置的,你可以启用autoload zsh/files它,因为zsh's.*不包括.也不..适用于rm -rf .. 所以在zsh,你可以这样做:

autoload zsh/files
rm -rf .
Run Code Online (Sandbox Code Playgroud)

在 Linux 上,您可以执行以下操作:

rm -rf /proc/self/cwd/
Run Code Online (Sandbox Code Playgroud)

清空当前目录或:

rm -rf /dev/fd/3/ 3< some/dir
Run Code Online (Sandbox Code Playgroud)

清空任意目录。

(注意尾随/

在 GNU 系统上,您可以执行以下操作:

find . -delete
Run Code Online (Sandbox Code Playgroud)

现在,如果当前目录只有几个条目并且大部分文件都在子目录中,那么这不会产生显着差异,并且rm -rf -- *可能是您可以获得的最快速度。预计rm -rf(或删除每个文件的任何内容)都是昂贵的,因为这意味着读取所有目录的内容并调用unlink()每个条目。unlink()它本身可能非常昂贵,因为它涉及修改已删除文件的 inode、包含该文件的目录以及一些文件系统映射或其他空闲区域。

rm并且find(至少 GNU 实现)已经按照每个目录中的 inode 编号对文件列表进行排序,这可以在 ext4 文件系统上的性能方面产生巨大差异,因为它减少了对底层块设备的连续更改次数(或彼此靠近)inode 按顺序修改。

rsync 按名称对文件进行排序,这可能会大大降低性能,除非按名称顺序恰好与按枚举顺序匹配(例如从文件名的排序列表创建文件时)。

rsync在某些情况下可能会更快的一个原因是它似乎没有采取安全预防措施来避免竞争条件,如果在它像rmfind做一样工作时用符号链接替换目录,则可能导致它下降到错误的目录中。

进一步优化:

如果您知道目录树的最大深度,则可以将其传递给find

find . -maxdepth 3 -delete
Run Code Online (Sandbox Code Playgroud)

这样就find不必尝试读取深度 3 的目录内容。


Oth*_*eus 8

最快的是用rm -rf dirname。我在 RedHat6.4 上使用了 ext3 文件系统的快照挂载点,其中包含 140520 个文件和 9699 个目录。如果rm -rf *很慢,可能是因为您的顶级目录条目有很多文件,并且 shell 正忙于扩展*,这需要额外的 readdir 和 sort 。上一个目录并执行rm -rf dirname/.

Method                    Real time    Sys time  Variance (+/-)
find dir -delete          0m8.108s     0m3.668s  0.055s
rm -rf dir                0m7.956s     0m3.640s  0.081s
rsync -delete empty/ dir/ 0m8.305s     0m3.918s  0.029s
Run Code Online (Sandbox Code Playgroud)

笔记:

  • rsync 版本:3.0.6
  • rm/coreutils 版本:8.4-19
  • find/findutils 版本:4.4.2-6