カイワレの大冒険 Third

技術的なことや他愛もないことをたまに書いてます

findコマンド使うときは、「prune」オプションを意識することが大事だという話し

findコマンドってすごく便利でxargsとかexecと合わせると色々できちゃうんですが、その分リスクも背負うので、リスクヘッジしておきましょうというお話し。

あるディレクトリ配下にこんなファイルがあったとします(適当でごめんなさい)。

# lla
drwxr-xr-x   6 root  wheel      204  3 21  2011 ./
drwxr-xr-x  51 root  wheel     1734  5 23 01:07 ../
drwx------   4 root  wheel      136  8 12  2010 cores/
-rw-r--r--   1 root  wheel  4912297 10 16  2011 log.nmbd
-rw-r--r--   1 root  wheel  5123798  3 21  2011 log.nmbd.old
-rw-r--r--   1 root  wheel   198900 10 16  2011 log.smbd

それで、「old」という文字列を含むファイルだったり、「log」という文字列を含むファイルを削除したいとする。

まぁ、-nameで指定するglobもそこまで複雑なパターンじゃないので、ざっくり書いたとする。んで、-mminをつけて、少し時間経ったものじゃないと対象にしないとする。

# find /var/log/sample -type f -mmin +360 -name '*log.*' -print0 | xargs -0 ls
/var/log/sample/log.nmbd    /var/log/sample/log.nmbd.old    /var/log/sample/log.smbd

その結果、こんな風にわりとヒットしてくれていいんですが、何よりも怖いのは「cores/」ディレクトリに対する処理がなんも書かれてないということでございます。

「-print0」とかじゃなくて、「| xargs -0 rm -rf」とか入ってる場合なんかはもっとそうで、万全には万全を期しておいたほうがいいと思うんですな。

なので、その場合は「-prune -o」を加えることで、除外パターンを加え、-pruneの条件がtrueだった場合のみ、そのパターンにマッチするもの除いて-o以下が処理されるようにしましょう。

# find /var/log/sample -type d -name "cores" -prune -o -mmin +360 -name '*log.*' -print0 | xargs -0 ls (※修正しました)
/var/log/sample/log.nmbd    /var/log/sample/log.nmbd.old    /var/log/sample/log.smbd

※-type fとしていましたが、上記の例はcoresディレクトリが対象となるため、-type dの間違いです。ご指摘頂きありがとうございます!!

アプリによってはlog/以下に.pidがあったり、あまりいじりたくない部分があるから、そういうケアはしておきましょうという話しでした。

まぁ、手動とかバッチでこの辺やるよりはlogrotateとか違うソリューションのほうがベターかなーという気がしますでおすし。