使用 find 搭配 rm 删除大量档案
在一个风和日丽的夜晚,我坐在家里看著电视,后来手机一阵响起,结果是杨老师发现一台主机发生异常,伺服器的 /var/spool/mqueue 目录被塞了一堆还没有寄出的信件,而当时没有把 /var/spool 另外分割出来,所以也影响到了系统 root (/) 区块,只剩六百多 MB 可以使用,这时一想会有几个可能.
一开始只有想到这两个原因,但是可要把被吞掉的空间给吐出来,所以就打算把所有的 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