从目录中删除数十亿个文件,同时查看进度


36

我有一个30 TB的目录,其中包含数十亿个文件,这些目录正式是所有JPEG文件。我正在删除文件的每个文件夹,如下所示:

sudo rm -rf bolands-mills-mhcptz

该命令仅运行,无论是否运行,均不显示任何内容。

我想看到它正在删除文件或命令的当前状态是什么。


19
没有答案:有时备份要保留的内容,格式化和还原要保留的内容会更快。其他答案: unix.stackexchange.com/questions/37329/...
埃里克·塔

2
如果您只想了解进度,而不是知道已删除了哪些特定文件,则可以运行“ df / dev / sd_whatever_the_drive_is”。
jamesqf '16

11
您如何最终在单个目录中保存数十亿个文件?
与莫妮卡(Monica)

1
@MichaelHampton但是,如果文件不是单独的数据集,则可能需要很长时间。(上ZFS)serverfault.com/questions/801074/...
v7d8dpo4

5
数十亿个文件,对吧?尝试rm -ri。应该会很好玩!
OldBunny2800 '16

Answers:


98

您可以使用rm -v具有rm打印一行每个文件删除。这样,您可以看到rm删除文件确实可以正常工作。但是,如果您有数十亿个文件,那么您将看到的rm只是仍在工作。您将不知道已经删除了多少文件,还剩下多少。

该工具pv可以帮助您估算进度。

http://www.ivarch.com/programs/pv.shtml

这里是你将如何调用rmpv使用示例输出

$ rm -rv dirname | pv -l -s 1000 > logfile
562  0:00:07 [79,8 /s] [====================>                 ] 56% ETA 0:00:05

在这个人为的示例中,我告诉您pv1000文件。来自的输出pv显示562已被删除,经过的时间为7秒,完成的估计时间为5秒。

一些解释:

  • pv -l使得pv通过换行,而不是字节数
  • pv -s number告诉pv总数是多少,以便可以给您一个估计。
  • 重定向到logfile最后是干净的输出。否则,来自的状态行pv会与来自的输出混淆rm -v。奖励:您将拥有删除内容的日志文件。但是请注意,文件将变得很大。/dev/null如果不需要日志,也可以重定向到。

要获取文件数,可以使用以下命令:

$ find dirname | wc -l

如果有数十亿个文件,这也可能需要很长时间。您也可以pv在这里使用以查看它的计数

$ find dirname | pv -l | wc -l
278k 0:00:04 [56,8k/s] [     <=>                                              ]
278044

在这里它说花费了4秒来计算278k文件。结尾(278044)的确切计数是的输出wc -l

如果您不想等待计数,则可以猜测文件数,也可以pv不经估计使用:

$ rm -rv dirname | pv -l > logfile

这样,您将无法完成估计,但至少您会看到已经删除了多少个文件。/dev/null如果不需要日志文件,请重定向到。


Nitpick:

  • 您真的需要sudo吗?
  • 通常rm -r足以递归删除。不需要rm -f

5
很好地使用pv,假设计算数十亿个文件并不太昂贵;-)。(这可能需要花费与rm预计的时间差不多的时间!)
Stephen Kitt,2016年

7
@StephenKitt这是真的惹恼了我(和许多其他人)有关Windows文件实用程序:它总是,没有失败,计算其中,除非该驱动器的数量和删除文件前的大小多少慢于处理器,几乎需要只要实际删除!
wizzwizz4 2016年

@ wizzwizz4确实!除了IIRC之外,它还具有更多的功能-它在删除任何内容之前检查它是否可以删除所有内容,以增加删除“全部或全部”的机会。很多年前,我为Windows编写了一个文件系统驱动程序,我们不得不处理很多怪异的事情,其中​​包括一些与Explorer删除有关的方式,但是我不记得这些细节。(我确实记得创建文件夹涉及写入和删除新文件夹中的文件!)
Stephen Kitt

7
@StephenKitt也许我弄错了,但不是瓶颈,除了磁盘访问之外,终端输出还没有?我相信pv,即使输入了进度条,它也只能每秒刷新一次。因此,终端仅需要显示一行,而不是每秒显示一吨。pv只需要为它遇到的每个换行增加一个计数器;它必须比自动换行要快,而在终端中显示一条线要快得多。我认为以pv这种方式运行会导致文件删除比简单删除要快rm -rv
JoL

1
@skywinderrm -rv dirname | pv -l -s $(find dirname | wc -l) > logfile
lesmana

28

查看lesmana的答案,它比我的要好得多-特别是最后一个pv示例,rm如果您指定/dev/null而不是,它的时间不会比原始的寂静时间长很多logfile

假设您rm支持该选项(由于您正在运行Linux,所以可能会支持),则可以使用-v以下命令以详细模式运行它:

sudo rm -rfv bolands-mills-mhcptz

正如许多评论者所指出的那样,这可能会非常慢,因为终端会生成并显示大量的输出。您可以改为将输出重定向到文件:

sudo rm -rfv bolands-mills-mhcptz > rm-trace.txt

并观察的大小rm-trace.txt


5
实际上,由于所有输出都已生成并呈现到终端,这实际上可能会减慢删除速度:)
rackandboneman

2
当然会慢下来。数十亿行写入文件不会在零时间内发生。
user207421 '16

23

另一个选择是观察文件系统上文件的数量减少。在另一个终端中,运行:

watch  df -ih   pathname

使用的节点数将随着rm进度的减少而减少。(除非文件大多具有多个链接,例如,如果树是使用创建的cp -al)。这根据文件(和目录)的数量跟踪删除进度。 df没有-i将跟踪使用的空间。

您还可能会iostat -x 4看到每秒的I / O操作(以及kiB / s,但这与纯元数据I / O不太相关)。


如果您对rm当前正在处理哪些文件感到好奇,可以将其附加strace到该文件上,并观察unlink()终端上的(和getdents)系统调用。例如sudo strace -p $(pidof rm)。您可以^crm不中断的情况下分离它。

我忘记了是否将rm -r更改目录添加到要删除的树中;如果是这样,你可以看看/proc/<PID>/cwd。它/proc/<PID>/fd可能经常打开一个目录fd,因此您可以查看该目录以查看您的rm进程当前正在查看什么。


2
df -ih确实是一种很好的观察rm进度的廉价方法。
史蒂芬·基特

顺便说一句,这在BTRFS上不起作用,在BTRFS中,使用索引节点的计数始终为零。:(同为FAT32,但你可能没有数十亿个文件对您的/bootEFI系统分区。
彼得·科德斯

4

尽管以上所有答案都可以使用rmrm但实际上删除大量文件的速度可能相当慢,正如我最近观察到的,从.tar存档中提取约100K个文件实际上比删除它们花费的时间更少。尽管这实际上并不能回答您提出的问题,但是更好地解决问题的方法可能是使用其他方法来删除文件,例如,对此问题的最高评价之一。

我个人最喜欢的方法是使用rsync -a --delete。我发现此方法的执行速度足够快,因此值得比该问题最受好评的答案更易于使用。在该问题中,作者编写了一个您需要编译的C程序。(请注意,这会将正在处理的每个文件输出到stdout,就像rm -rv;;这会使处理速度减慢一个惊人的数量。如果您不希望此输出,请使用rsync -aq --delete或将输出重定向到一个文件。)

该答案的作者说:

该程序现在(在我的系统上)将在43秒内删除1000000个文件。与之最接近的程序是rsync -a --delete,该程序耗时60秒(它也按顺序进行删除,但不会执行有效的目录查找)。

我发现这足以满足我的目的。从该答案中可能也很重要,至少在使用ext4的情况下:

作为一种预见,应该删除受影响的目录并在之后进行重新制作。目录的大小只会不断增加,并且由于目录的大小,即使其中包含几个文件,目录的性能也可能仍然很差。


嗯,我本来期望rm和/或find --delete有效率。关于按顺序删除以避免在删除时b树重新平衡的有趣观点。不知道有多少适用于其他文件系统。XFS也不适合每个目录包含数百万个文件。关于BTRFS的IDK,但我的印象是这可能对这类事情有好处。
彼得·科德斯

那第二引号不取决于文件系统的类型吗?
Menasheh

@Menasheh好点,我将其编辑为答案。
Hitechcomputergeek

3

您可以做的一件事是rm在后台启动该进程(无输出,因此不会降低速度),然后使用一个简单的(a)命令在前台对其进行监视:

pax> ( D=/path/to/dir ; rm -rf $D & while true ; do
...>   if [[ -d $D ]] ; then
...>     echo "$(find $D | wc -l) items left"
...>   else
...>     echo "No items left"
...>     break
...>   fi
...>   sleep 5
...> done )

27912 items left
224 items left
No items left

pax> _

find/wc组合可以用任何能够为您提供所需单位的工具代替。


(a)与核物理,黎曼假设或为圣诞节买我妻子的东西相比,相对来说比较简单:


0

前一段时间,我写了一些东西来打印行的打印速度。您可以运行rm -rfv | ./counter,它将以每秒/分钟的速度打印行数。尽管不是直接的进度,但它会为您提供有关进度的反馈,也许是rm徘徊在网络文件系统中或类似的东西?

链接到代码在这里:

http://www.usenix.org.uk/code/counter-0.01.tar.gz

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.