.nリネームでログを退避する

Linuxの/var/logの下のシステムログには一定の間隔やあるタイミングで古いログが退避されるものがあります。たとえばboot.logは一週間おきに退避されるとか。

実際のシステム開発の現場でも、これにならって末尾に.nを付与していくという運用がよくなされます。

これを自宅で運用しているシステムで肥大化し続けている各種ログにも適用してみました。シェルスクリプトでやってしまえる内容ですが、あえてPerlで。


まず、単純に番号が大きい順に新しくなるようにするなら新しく退避されるものだけをリネームすればいいのでとても単純です。hoge.log.1、hoge.log.2、hoge.log.3がある状態なら新しく退避されるログにはhoge.log.4と命名する感じです。

chdir $dir;
my $i = 1;
$i++ while -e $log.'.'.$i;
rename $log, $log.'.'.$i;

先のLinuxのシステムログのように番号が若いほど新しいという風にするためには、都度リネームする必要が出てくるのでたとえばこんな感じに。*1

chdir $dir;
opendir DIR , '.';
for my $each ( grep /$log/, reverse sort readdir DIR ) {
    ($each =~ /\.(\d)$/) ? rename $each, $log.'.'.($1+1) : rename $each, $log.'.1';
}
closedir DIR;

こういうケースだとreverseがとても有用ですね。

*1:三項演算子で書く必要は特にないけど

grep -v grepしないで済む方法

こちら経由でこのエントリで知りました。


プロセスをgrepするときに

ps -ef | grep hoge | grep -v grep

ってやるのはださいので、代わりに

ps -ef | grep [h]oge

ってやれば同値だよという。*1

[ と ] で囲まれた文字のリストは、そのリスト中に含まれるどれか 1 文字にマッチします。
http://www.linux.or.jp/JM/html/GNU_grep/man1/grep.1.html

[h]ogeのマッチする文字列は「*hoge*」になるので、引数である「[h]oge」はアンマッチになります。


こういうのって実際に見てしまえば簡単ですが、自分で思いつくのはなかなか。

*1:はじめ、作業中によくやる自UNIXユーザ名のgrepで試して、grepのプロセスも含まれてしまって「あれ?」とかなってた・・これはさすがにgrep -v grepするしかなさそう