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

CGIテクニック集トップへ





概要

古いテンポラリファイルを自動削除します。スクリプトを実行すると一時的に作成したサムネイルやzipファイルなどを一定時間経過後に削除します。リサイズイメージファイルリスト3で使われています。 複数のディレクトリから古いファイルを自動削除するにはこちらを参照ください。

必用な処理

  1. オープンするディレクトリを開く
  2. ディレクトリ内のファイルから該当する物を配列に挿入
  3. それらのファイルの更新時間をチェック
  4. 更新時間が設定時間以上経過していたら削除する

サンプルコード

 my $prefix = 'tmp_';
 opendir(TMPDIR, "$tmpdir");
 my @tmplist = grep /^$prefix.*\.tmp$/, readdir TMPDIR;
 closedir(TMPDIR);
 
 my $expire = 60;
 my $now = time;
 foreach my $tmpfile (@tmplist){
        my $mtime = (stat("$tmpdir/$tmpfile"))[9];
        if ($now > $mtime + $expire * 60){
            unlink("$tmpdir/$tmpfile");
        }
 }

コードの解説

 my $prefix = 'tmp_';

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

 opendir(TMPDIR, "$tmpdir");
 my @tmplist = grep /^$prefix.*\.tmp$/, readdir TMPDIR;
 closedir(TMPDIR);

テンポラリディレクトリ$tmpdirの中のtmp_*.tmpファイルを探して配列@tmplistに入れます。 opendirで$tmpdirをオープンします。 ファイルハンドルTMPDIRの内容をreaddirで取り込みます。その出力をgrepによりtmp_*.tmpのファイルのみ配列@filelistに入力します。ファイルハンドルTMPDIRに対して必用な処理はこれだけなのでTMPDIRをクローズします。

 my $expire = 60;

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

 my $now = time;

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

 foreach my $tmpfile (@tmplist){
        my $mtime = (stat("$tmpdir/$tmpfile"))[9];
        if ($now > $mtime + $expire * 60){
            unlink("$tmpdir/$tmpfile");
        }
 }

@tmplistに入っているファイルの更新時間を一つずつチェックし60分以上変更後60分以上経過したかをチェックし、そうであれば削除します。

 my $mtime = (stat("$tmpdir/$tmpfile"))[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("$tmpdir/$tmpfile");

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

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

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

 unlink("$tmpdir/$tmpfile");

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

関連するCGIテクニック

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