File::Findを使って複数ディレクトリ内の古いテンポラリファイルを自動削除

CGIテクニック集トップへ





概要

File::Findを使って複数ディレクトリ(フォルダ)内の古いテンポラリファイルを自動削除します。スクリプトを実行すると一時的に作成したサムネイルやzipファイルなどを一定時間経過後に削除します。 File::Findを使わないで自動削除する古いtemporaryファイルを自動削除も参照ください。

必用な処理

  1. File::Findを読み込む
  2. ファイルを検索したいディレクトリを設定する
  3. ディレクトリを開く
  4. ディレクトリ内のファイルから該当する物を配列に挿入
  5. それらのファイルの更新時間をチェック
  6. 更新時間が設定時間以上経過していたら削除する
  7. 設定されているディレクトリが終わるまで繰り返す

サンプルコード

 use File::Find;
 
 my $prefix = 'tmp_';
 my $expire = 60;
 my $now = time;
 
 my @tmpdir = qw(tmpdir1 tmpdir2 tmpdir3);
 
 find(\&wanted, @tmpdir);
 
 sub wanted { 
    return unless (/^$prefix.*\.tmp$/ and -e );
    my $mtime = (stat("$_"))[9];
    if ($now > $mtime + $expire * 60){
        unlink("$_");
    }
 }

コードの解説

 my $prefix = 'tmp_';

テンポラリファイルをtmp_*.tmpと予め設定しておいたと仮定します。便宜上のためprefixであるtmp_を変数に入れておきます。これは必ずしも必用ではありません。

 my $expire = 60;

$tmpdir内の60分以上経ったファイルのみを削除するので$expireに60を入れます。時間情報は基本的に秒なので後に60倍して秒数として扱います。

 my $now = time;

現在時刻を変数$nowに保存します。

 my @tmpdir = qw(tmpdir1 tmpdir2 tmpdir3);

@tmpdirにテンポラリファイルがあるディレクトリを設定します。複数のディレクトリを配列に指定することができます。

 find(\&wanted, @tmpdir);

findメソッドで@tmpdirに指定されているディレクトリに入り、その中のそれぞれのファイルに対して&wantedを実行する。第一引数のファンクションはリファレンスを渡す。

 sub wanted { 
    return unless (/^$prefix.*\.tmp$/ and -e );

&wanted内では、プロセスがそのディレクトリに入り、$_にファイル名が挿入される。 処理として、現在のファイルがテンポラリファイルとして指定してあるtmp_*.tmpであり、且つ存在してあれば次に進み、そうでなければファンクションを抜ける。

    my $mtime = (stat("$_"))[9];

ファイルの更新時間を取得します。stat関数によりそのファイルの属性を配列にて取得することができます。statが返す配列の10番目の要素(0から始まる要素番号9)が更新時間情報なのでそれを$mtimeに格納します。他の返り値は捨てています。時間はepochなので1970年1月1日0時0分0秒からの秒数になります。

他のstatの返り値は、

 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,
     $mtime,$ctime,$blksize,$blocks)=stat;

のようになります。 この場合アクセス時間は$atime, inode変更時間は$ctimeに格納されます。$sizeによりファイルサイズも取得できます。

    if ($now > $mtime + $expire * 60){

現在時刻$nowがファイルの変更時間($mtime)+設定分($expire)*60秒以上であればファイル変更後60分以上経過したということなのでifブロックを実行します。この式が偽であればifブロックは実行されないのでファイルは削除されません。

        unlink("$_");
    }
 }

ifブロック内のunlinkでそのファイルを削除します。

関連するCGIテクニック

zipファイルの作り方
サーバー上の古いテンポラリファイルを自動削除