Bashで指定ディレクトリのファイルから一定期間経過したものを削除する

スポンサーリンク

先日、サーバー上の指定ディレクトリの中にあるファイルで、タイムスタンプが一定期間以上前のものは削除する処理を作る必要がありました。
PHPやRuby、Pythonなどを利用する方法もありますが、
元がcrontabでShellを実行するしていて、その処理への追加だったので、そのままShell内で実行できるようにしました。

スポンサーリンク

処理の概要

処理の手順は次の通りです。
1. 現時刻と削除リミット期間を算出する
2. 指定ディレクトリのファイルを取得し、1つずつ処理する
3. 取得ファイルのタイムスタンプを取得する
4. 取得したタイムスタンプと現時刻との差分を算出する
5. 取得した差分と削除リミット期間を比較し、期間を過ぎていたら削除する
6. 3-5をファイルの数だけ繰り返す

完成コード

完成したコードは以下の様になります。
このコードでは、Shellの実行時に対処するディレクトリを引数として与えるようにしています。
また、削除リミット期間は7日間としています。

delete_sample.sh

#!/bin/bash

cd $1
filename="*"
now_time=`date +%s`
delete_limit=$((60 * 60 * 24 * 7))
for filepath in $filename; do
  file_time=`date -r $filepath +%s`
  diff_time=$(($now_time - $file_time))
  if [ $diff_time -gt $delete_limit ]; then
    rm -f $filepath
  fi
done

実行例(/home/guest/log内のファイルに対して処理を行う)
delete_sample /home/guest/log

コードの解説

簡単にコードの解説として、簡単にコードの説明をしてみます。

処理の対象ディレクトリに移動する

cd $1

この$1は引数で与えられた値を示しているので、ここを次の様に固定記述にすれば、引数での指定が不要となります。
cd /home/guest/log

現時刻をUTCからの時刻(1970-01-01 00:00:00からの時刻)で取得する

now_time=`date +%s`

削除対象となるリミット期間を算出して、delete_limit変数に保持する

delete_limit=$((60 * 60 * 24 * 7))

ファイル一覧を取得し、1つずつファイルを取得して処理を行う

filename="*"
for filepath in $filename; do
  # 処理
done

ファイルのタイムスタンプをUTCからの時刻で取得し、file_time変数に保持する

file_time=`date -r $filepath +%s`

現時刻とファイルのタイムスタンプの差分(ファイルが作成されてからの経過時間)を算出し、diff_time変数に保持する

diff_time=$(($now_time - $file_time))

ファイルが作成されてからの時間が指定時間を過ぎていたら、処理を行う

if [ $diff_time -gt $delete_limit ]; then
  # 処理
fi

ファイルを削除する

rm -f $filepath

改良

このコードはファイルを削除してしまいますが、コードを少し変更することで別の処理を行うことや、改良することができます。

一定期間経過のファイルを抽出する

一定期間経過したファイルをリストアップさせることをできます。
その場合、11行目の記述(rm -f $filepath)を以下のように書き換えます
echo $filepath

一定期間経過したファイルを別ディレクトリに移動させる

一定期間経過したファイルを別ディレクトリに移動させることもできます。
その場合、11行目の記述(rm -f $filepath)を以下のように書き換えます。
この例では、対象ディレクトリの1階層上にoldディレクトリがあり、そこに移動させることを想定しています。
mv $filepath ../old/

経過時間も引数で指定する

経過時間も引数で与えることもできます。
その場合、6行目の記述(delete_limit=$((60 * 60 * 24 * 7)))を以下のように書き換えます。
delete_limit=$((60 * 60 * 24 * $2))
この場合の実行例は以下のようになります。(30日間以上経過したファイルを削除)
delete_sample /home/guest/log 30

おわりに

今回は私の実行したShellの処理系の関係でBashを想定していますが、他のShellでも同じ様な記述で対応することができると思います。
一定期間経過したファイルを削除する様な処理は、時々必要になる事があると思いますので、参考にしていただければ幸いです。

スポンサーリンク