古いファイルを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
とするか.