一个程序创建了许多嵌套的子文件夹。我尝试使用命令
rm -fr *
将它们全部删除。但速度非常慢。我想知道有没有更快的方法来删除它们?
答案1
从该目录中删除它们的最快方法是将它们移出那里,然后只需在后台删除它们即可:
mkdir ../.tmp_to_remove
mv -- * ../.tmp_to_remove
rm -rf ../.tmp_to_remove &
这假设您的当前目录不是某些已安装分区的顶层(即../.tmp_to_remove
位于同一文件系统上)。
如果您有任何以--
.mv
-
上面的代码会在不到一秒的时间内从当前目录中删除文件,因为它不必递归地处理子目录。从文件系统中实际删除树需要更长的时间,但由于它不碍事,因此其实际效率应该不那么重要。
答案2
rsync
出奇的快速和简单。您必须先创建空目录,
mkdir 空目录 rsync -a --删除空目录/你的目录/
yourdirectory/
是您要从中删除文件的目录。
答案3
最快的是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
笔记:
- rsync版本:3.0.6
- rm/coreutils 版本:8.4-19
- 查找/findutils版本:4.4.2-6
答案4
的一个问题rm -rf *
,或更正确的等价物rm -rf -- *
是,shell 首先列出当前目录中的所有(非隐藏)文件,对它们进行排序并将它们传递给rm
,如果当前目录中的文件列表很大,则为会增加一些不必要的额外开销,如果文件列表太大,甚至可能会失败。
通常,您会这样做rm -rf .
(这也有删除隐藏文件的好处)。但大多数rm
实现(包括所有符合 POSIX 的实现)将拒绝这样做。原因是某些 shell(包括所有 POSIX shell)具有 glob 扩展.*
将包含.
和的错误功能..
。这意味着rm -rf .*
将删除当前目录和父目录,因此rm
已进行修改以解决这些 shell 的错误功能。
有些贝壳pdksh
(以及其他福赛斯贝壳衍生物),zsh
或者fish
没有这种错误特征。zsh
有一个rm
内置的,您可以启用autoload zsh/files
它,因为zsh
's.*
不包含.
也..
不能与 一起使用rm -rf .
。所以在 中zsh
,你可以这样做:
zmodload zsh/files
rm -rf .
在 Linux 上,您可以执行以下操作:
rm -rf /proc/self/cwd/
清空当前目录或:
rm -rf /dev/fd/3/ 3< some/dir
清空任意目录。
(注意后面的/
)
在 GNU 系统上,您可以执行以下操作:
find . -delete
现在,如果当前目录只有几个条目,并且大部分文件都在子目录中,那么这不会产生显着差异,并且rm -rf -- *
可能是您可以获得的最快速度。预计rm -rf
(或删除每个文件的任何内容)都会很昂贵,因为这意味着读取所有目录的内容并调用unlink()
每个条目。unlink()
它本身可能非常昂贵,因为它涉及修改已删除文件的索引节点、包含该文件的目录以及某些文件系统映射或其他可用区域。
rm
并且find
(至少 GNU 实现)已经按每个目录中的 inode 编号对文件列表进行排序,这可以在 ext4 文件系统上的性能方面产生巨大差异,因为它减少了连续(或彼此接近) inode 按顺序修改。
rsync
按名称对文件进行排序,这可能会大大降低性能,除非按名称顺序恰好与按 inum 顺序匹配(就像从文件名排序列表创建文件时一样)。
在某些情况下可能更快的原因之一是,它似乎没有采取安全预防措施来避免竞争条件,如果目录在工作时被符号链接替换,则rsync
可能导致它进入错误的目录。rm
find
进一步优化:
如果您知道目录树的最大深度,您可以将其传递给find
:
find . -maxdepth 3 -delete
这样就find
不必尝试读取深度 3 的目录内容。
¹ 另请参阅globskipdots
bash 5.2+ 中的选项