結論から書くとls -f | head -n <int> | perl -lne unlink
どうしてこうなった
オプションを事故ったコマンドを実行して放置した結果、大量の中間ファイルを生成してしまう羽目に。
その数億単位。
ls
コマンドがうんともすんとも言わなくなったせいで、最初は何が起きているのかさっぱり分からなかった。どうやらデフォルトではls
やrm
はファイルをリストアップしようとするせいなのか、あまりに大量のファイルを扱おうとするとメモリを食いつぶしてしまうようだ。find
とか色々試してみたけど標準出力に帰ってきたものは誰一人としていなかった。
幸い、ファイル名が規則的だったので必要なファイルは隔離できた。ディレクトリごと削除できればいいのに。。。
解決方法
まずls
に-f
オプションをつける。
デフォルトでは表示を整形するためにls
コマンドはファイルをソートしたりしているのだが、このオプションを付ければディスク上にある順で逐次ファイル名を出力してくれる。
これをhead
でも使って適当な数ずつ処理する。
削除はrm
でもいいのだが、何やらperl
のunlink
を使うと速いらしい1。
というわけで適当にスクリプトを書くとこうなる。
count=0
while [ $count -lt 100 ]; do
ls -f ./directory | head -n 1000 | perl -lne unlink
count=`expr ${count} + 1`
sleep 5
done
ファイル数に合わせてループ回数を、負荷がかかり過ぎないよう一度に消す数とお休みする時間の長さを適当に設定。今回の場合はファイルの総数を知れたのが不幸中の幸い2。
もっともファイル数が分かった所で相応の時間がかかるのは変わらないので、どの道、そんな大量のファイルを消そうとするとスクリプトを走らせて放置することになる。
-
ある名前を持つファイルが存在するかどうかは確認できるので、ファイル名が規則的に付いているなら二分探索か何かでどうにかできる。 ↩