概要

研究で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では,タブ補完すると以下のようにカレンダー表示され,指定の日付を選べる. find-completion

-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 とするか.

参考

findで時間を指定する~mtime,ctime,atimeとmmin,cmin,amin - grep Tips *