MENU

古いログやバックアップを日数指定で自動削除する実務手順

ログやバックアップファイルは放置すると、ディスク使用率が静かに上昇し続けます。気づいたときには空き容量が逼迫していた、というケースはLinuxサーバーの運用でよく起こります。

この記事では、findコマンドの日数指定オプションを使って「削除前に対象を確認する」「確認できたら安全に削除する」「cronで定期的に自動削除する」という一連の流れをまとめています。更新日時でファイルを探すだけでなく、削除後の確認や定期運用まで一通り押さえます。

目次

削除前に対象ファイルを必ず確認する

削除コマンドをいきなり実行するのは危険です。まず-printまたは-lsで対象ファイルを一覧表示し、意図したものだけが選ばれているかを確認してください。

以下は、/var/log/myapp配下で更新日時が30日より古い.logファイルを一覧表示するコマンドです。

find /var/log/myapp -type f -name "*.log" -mtime +30 -print

-mtime +30は「最終更新時刻が30日より前のファイル」を意味します。+30の+は「それより古い」、-30は「それより新しい」、符号なしの30は「ちょうど30日前の24時間内」を指します。削除目的では通常+を使います。

ファイル数だけでなくサイズや日付も確かめたい場合は-lsを使うと確認できます。

find /var/log/myapp -type f -name "*.log" -mtime +30 -ls

-type fを付けることで通常ファイルのみに絞り込み、シンボリックリンクやディレクトリが誤って対象に入るのを防げます。

対象を確認したら削除を実行する

一覧で内容を確認したら、-printを-deleteに置き換えて削除します。-deleteはfindの組み込みアクションで、rmを別途呼び出すよりシンプルに記述できます。

find /var/log/myapp -type f -name "*.log" -mtime +30 -delete

ファイルを削除した後、空になったサブディレクトリも合わせて消したい場合は、ファイルを先に削除してから空ディレクトリを探す順序で実行します。

# ファイルを先に削除する
find /var/log/myapp -type f -name "*.log" -mtime +30 -delete

# 空になったサブディレクトリを削除する(起点ディレクトリ自体は残す)
find /var/log/myapp -mindepth 1 -type d -empty -delete

-mindepth 1を指定すると、検索の起点となるディレクトリ自体(ここでは/var/log/myapp)が削除対象に含まれなくなります。また、削除範囲を特定のディレクトリ直下に限定したい場合は-maxdepth 1を追加します。

find /var/log/myapp -maxdepth 1 -type f -name "*.log" -mtime +30 -delete

削除後に残存ファイルを確認する

削除が正しく行われたかは、同じ条件で-printを再実行して確認できます。

find /var/log/myapp -type f -name "*.log" -mtime +30 -print

何も出力されなければ対象ファイルは削除されています。ディスク使用量の変化はduで確認できます。

du -sh /var/log/myapp

cronで定期的に自動削除する

手動での削除を継続するのは手間がかかります。cronに登録すれば、毎日決まった時刻に自動削除できます。

削除処理をシェルスクリプトにまとめておくと、crontabをすっきりさせられます。以下を/usr/local/bin/cleanup_logs.shとして保存します。

#!/bin/bash
LOG_DIR=/var/log/myapp
DAYS=30

find "$LOG_DIR" -type f -name "*.log" -mtime +"$DAYS" -delete
find "$LOG_DIR" -mindepth 1 -type d -empty -delete

スクリプトに実行権限を付与します。

chmod +x /usr/local/bin/cleanup_logs.sh

crontab -eで編集画面を開き、以下の行を追加します。実行結果をログに残すことで、いつ・どのような結果だったかをあとから確認できます。

0 3 * * * /usr/local/bin/cleanup_logs.sh >> /var/log/cleanup.log 2>&1

この例では毎朝3時に実行します。>> /var/log/cleanup.log 2>&1で標準出力とエラー出力を追記形式で記録します。cronの環境ではPATHが通っていないことがあるため、スクリプト内のコマンドはフルパス(/usr/bin/findなど)で書くと安全です。

よくあるつまずきと対策

-mtime の基準は「ファイル内容の更新日時」

-mtimeはファイルの内容が最後に変更された日時(modification time)を基準にします。ログローテートなどで中身が書き換えられると、ファイル名に古い日付が含まれていても-mtimeの値はリセットされます。アクセス日時を使いたい場合は-atime、メタデータの変更日時なら-ctimeを使います。目的に応じて使い分けてください。

cronの実行ユーザーに削除権限があるか確認する

crontab -eで登録したジョブは、そのユーザーの権限で動きます。root所有のファイルを一般ユーザーのcronで削除しようとすると「Permission denied」が発生します。削除対象ファイルの所有者と、cronを設定するユーザーが一致しているかを事前に確認してください。

cleanup.log 自体が肥大化しないよう管理する

実行結果をcleanup.logに追記し続けると、そのログ自体がディスクを圧迫します。一般的には、logrotateの設定にcleanup.logを追加するか、cronのコマンドを>> /dev/null 2>&1にしてログを残さないか、いずれかの方針を決めておくと安心です。

削除対象のパスに変数や相対パスを使わない

スクリプト内でパスを変数にする場合、変数が空になったときにfind / -delete相当の動作になるリスクがあります。変数には必ずデフォルト値を持たせるか、値が空でないことをスクリプトの先頭で確認するようにしてください。

#!/bin/bash
LOG_DIR=/var/log/myapp
DAYS=30

# LOG_DIRが空の場合は処理を中断する
[[ -z "$LOG_DIR" ]] && { echo "LOG_DIR is not set"; exit 1; }

find "$LOG_DIR" -type f -name "*.log" -mtime +"$DAYS" -delete

「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。

ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。

>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)

※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次