古いファイルをfindしてrmする
概要
研究でpcapファイルを扱うリアルタイム解析を行っており, 1分毎にパケットキャプチャの結果があるサーバーに定期的に転送される. ずっと解析プログラムを回し続けて1年が過ぎたとき,ついにストレージが…
tmpファイルも作れないためタブ補完すら効かない.
そこでこの期に定期的に削除するスクリプトを書くことにした (めんどくさくてやってなかった).
問題
- あるディレクトリ直下にこれまで約1年間にわたる1分毎のパケットキャプチャ結果が保存されている.なおセンサは複数のため,実に 個分のファイルとなる.
- ファイル数が非常に多く,愚直に
rm -f /path/to/dir/*.extとやるとArgument list too longとなる. - ある程度日数の経ったファイルは後の分析にもほぼ使わないので,これを自動で削除するようにしたい.
- 環境: Ubuntu 16.04 LTS (macOSなどBSD系のコマンドは一部↓のものだと使えない)
やったこと
たまに以下のような使い方を見かけるが,これだと引数が展開されてしまうため,
Argument list too long エラーが出るだろう.
$ find /path/to/dir/*.ext
-nameオプションは正規表現も使え,逐次的に探してくれるので楽.
今回は変更日時だけ監視するので良かったため, -mtime +日数 とした.
このオプションについては下の参考リンクが詳しい.
単に -mtime +X とすると 実質X+1日前より過去のファイルをすべて削除,となる.
これはコマンドを実行した日時から遡るためで,直感的な結果とはならない.
そこでこの基準をその日の24時としてしまうオプションが -daystart である.
ちなみにzshでは,タブ補完すると以下のようにカレンダー表示され,指定の日付を選べる.

-type f はよく使うオプションで,ファイルのみを出力する (ディレクトリは除かれる).
次に削除だが, find コマンド自体に -exec オプションがありfindした結果を
引数にして他のコマンドを実行することも可能だが,遅く自由度も低い.
以下の例では xargs を使う.
-P で並列化もできる.一気に xargs で渡してしまうと今度は rm の際にまた
Argument list too long エラーになるので,-n で一度に渡す引数の数を決める.
後はcrontabでそのまま回せるようにフルパスで書いて,一応意味なさそうだがログファイルに書き込ませる.
以上をまとめると,以下のコードとなる:
ちなみに消すファイル名を出力したい場合は
xargs で -t とするか,力技で -I{} sh -c "echo {}; rm -f {}"とするか,
rm -fv とするか.