使用 find 搭配 rm 删除大量档案

在一个风和日丽的夜晚,我坐在家里看著电视,后来手机一阵响起,结果是杨老师发现一台主机发生异常,伺服器的 /var/spool/mqueue 目录被塞了一堆还没有寄出的信件,而当时没有把 /var/spool 另外分割出来,所以也影响到了系统 root (/) 区块,只剩六百多 MB 可以使用,这时一想会有几个可能.

  1. 这台 server 有帮学校的 PC 做寄送信件,所以可能是广告信在寄出.
  2. 使用这台 server 做 mail 寄信的机器,可能是中毒,於是就不断的送信出去.

一开始只有想到这两个原因,但是可要把被吞掉的空间给吐出来,所以就打算把所有的 mail queue 都先砍了,当然,要先停掉 mail service.

在砍这些正在排队的信件时,发现一件事,就是里面的档案太多了,使用 ls 命令就变得超级迟顿,没有反应,使用 mailq 来看看到底是那些信被 queue 住也没办法,后来想想算了,只好全剖砍了,不要再玩下去,之后,很顺手的下了 rm -rf * 这下子呢,发生了一件很离奇的事,居然档案太多无法删除,第一次听到 rm 在 complain (我是听到的,杨老师是实作者,所以他有看到 ^^).

那个 error 是: bash: /bin/rm: Argument list too long

虽然无法删除,但是杨兄并不放弃,到主机面前,开启了 X Window 之后使用那 Linuxer 最常使用的鹦鹉螺 (nautilus) 开启到 /var/spool/mqueue. 喔 ~ 可以使用 X Window 来删呢 ! 后来想说即然 X Window 有这么大的本事,那么就用它来删了其它的 queue files 就好啦,於是挂上电话,放杨兄一个人努力的在机房删著 ...

当然我也没有闲著,电视剧刚好演完,於是开启我的工作伙伴,再度当网路潜水艇 ... 游著游著,突然想到,何不使用 find 来删除看看 ? 於是删回历史文件,发现一个命令就是 find ./ | xargs rm -rf 千万别小看这小小的指令,因为在我看完之后不久,杨兄打进来,说已经删到手软,这时也是晚上十点了,於是我就推荐了这个这道指令,嗯,很好,全都删了,还颇快的 ...

喔,还没说为什么会删到手软,是因为 nautilus 在 Load 目录时,是分批的,不是一次全部读,所以一次大约是几千封在读,删了之后,没想到又冒出了还有几千封 ... 真是吓死人,后来推论应该是分批的关系.

在下了 find ./ | xargs rm -rf 之后,还在讶异快速之余,就发现时间不多了,学校也要关门,所以就先 say bye bye,在现场苦命的杨兄也回家休息了.

分析:
rm 有最大一次删除的数量,所以当一个目录里有太多的档案或目录时,就会出现错误,小弟试过应该是在二万以下,而使用 find ./ | xargs rm -rf 的目的是先使用 find 列出档案,再导向到 xargs,xargs 再喂给 rm,在这里,xargs 会分批依照 rm 的最大数量喂给 rm,然后就可以顺利删除档案了。而真正的原因,有可能是 rm 的版本或是档案系统的问题,我也不再继续追就,反正能办好事就好 :)

下面提供当时小弟测试的一个小小 shell script

下载:mk-file.sh (这个 shell script 会有目录下产生 20000 个档案。)

接下来来做个小小测试:

root # mkfile.sh
root #

会产生 20000 个小档案,名称为 test-file-{1~19999}

直接使用 rm 去删除:

root # rm -rf test-file-*
-bash: /bin/rm: Argument list too long (会回应引数过长的讯息)

改搭配 find 来删除

root # find ./ -iname 'test-file-*' | xargs rm -rf
root # ls
mk-file.sh
root #

这样就顺利被删除了。

06/21/2006


首页