テックブログ

技術ネタ

元号とかtmpwatchとかタイムスタンプとか。。。

阿部です。
2018年も残すところ2ヶ月、「平成」は残り7ヶ月ですね。
・・・・・
キリが悪いとか、気にしません。

ちなみに、dateコマンドにロケール変数 ‘LC_TIME’ を
渡してあげると、元号表示になります。

# LC_TIME=ja_JP.utf8 date +'%EY'
平成30年

年末調整とか「何年だっけ?」となったら使ってみて下さい。

~~~~~

日々、ログとかバックアップとかメールとか○○○とか、
ファイルを溜め込んでいることと思います。

全部いらな~い、ならrmコマンド一発投げて終了です。

それでは、こんなときはどーしましょ?
・作成してから1週間以上経過してるヤツ消したい
・去年取得したヤツ全部消したい

ノーマルな人なら findコマンドで mtime 指定して
xargs でまとめて rm だと思います。

アブノーマルな人向けとゆーわけではありませんが、
tmpwatch なるコマンドがあります。
* RHEL7(CentOS7)からは標準パッケージから外れたみたいですね。

cron.dailyで同姓同名のスクリプトがクルクル回っているのですが
まさにこのスクリプトの中で活躍してるコマンドです。

/tmp や /var/tmp の下に保存していたファイルが、
「いつの間にか、誰かに消された! 」
と絶句した経験を持つ人いると思いますが、犯人はコイツ↓です。

# cat /etc/cron.daily/tmpwatch
---------------------------------------------------
#! /bin/sh
flags=-umc
/usr/sbin/tmpwatch "$flags" -x /tmp/.X11-unix -x /tmp/.XIM-unix \
-x /tmp/.font-unix -x /tmp/.ICE-unix -x /tmp/.Test-unix \
-X '/tmp/hsperfdata_*' -X '/tmp/.hdb*lock' -X '/tmp/.sapstartsrv*.log' \
-X '/tmp/pymp-*' 10d /tmp
/usr/sbin/tmpwatch "$flags" 30d /var/tmp
for d in /var/{cache/man,catman}/{cat?,X11R6/cat?,local/cat?}; do
if [ -d "$d" ]; then
/usr/sbin/tmpwatch "$flags" -f 30d "$d"
fi
done
---------------------------------------------------

コマンドの書式はこんな感じです。
tmpwatch [–test] [-u|-m|-c] [-f] [-x path] [-X pattern] time dirs

オプションを見ていきます。
—————————————————
–test テストモード
—————————————————
“-u” : atime 最後にアクセスした時刻
“-m” : mtime 最後に変更した時刻
“-c” : ctime 最後にinodeデータが変更された時刻
—————————————————
“-f” 強制執行
—————————————————
“-x” パスの除外
“-X” パターンの除外
—————————————————
他にも便利オプションがあるのでマニュアルでご確認下さい。

timeは分(m)、時間(h)、日(d)の指定ができます。
スクリプトの例でいくと
—————————————————
“10d” 10日経過してる
“30d” 30日経過してる
—————————————————

atime, mtime, ctime を単発で指定したときの動作は
まぁ、想像できると思います。
が、上記のスクリプトの中では3つのタイムスタンプが
指定されてますね。
—————————————————
flags=-umc
—————————————————

英語マニュアルをグーグル先生にブチ込むと
—————————————————
–atime、–ctimeまたは–mtimeオプションを組み合わせて使用すると、
ファイルの削除に関する決定は、これらの時間の最大値に基づいて行われます。
—————————————————
ふむ。。。ですね。

とりあえず叩いてみます。
適当にファイル作ります。

# touch test1

5分ほど放置して、mtimeを適当に変更します。

# touch -m -d "2017/10/29 05:36:14" test1

# stat test1
--------------------------------------------------
Access: 2018-10-29 03:00:10.011706703 +0900
Modify: 2017-10-29 05:36:14.000000000 +0900
Change: 2018-10-29 03:08:21.754706534 +0900
--------------------------------------------------

次、速攻で、テストモードで、”-umc” 指定して
“1分経過したファイルを削除” してみます。

# tmpwatch --test -umc 1m /root/

ヒットしません。

~1分経過~

# tmpwatch --test -umc 1m -d /root/
removing file /root/test1

ヒットしました。
atime, mtime, ctime の中で直近の時刻を持つ
コイツ↓が参照されたみたいです。
————————————————–
Change: 2018-10-29 03:08:21.754706534 +0900
————————————————–

ゴミならいっぱい持ってるので、もう少し検証してみます。
手頃なヤツがいました。

# stat monthly_maintenance7.sh
--------------------------------------------------
Access: 2018-09-18 02:48:15.170581785 +0900
Modify: 2018-09-14 09:15:04.949783177 +0900
Change: 2018-09-14 09:15:04.976782831 +0900
--------------------------------------------------

一番近い日時はコレ↓ですね。
————————————————–
Access: 2018-09-18 02:48:15.170581785 +0900
————————————————–

こんどは経過日数を指定してみます。
日数計算が面倒クサイ。。。こんなときはSELECT文です。

mysql> select datediff('2018-09-18', current_date());
+--------------------------------------------------------+
| datediff('2018-09-18', current_date()) |
+--------------------------------------------------------+
|                                                   -41 |
+--------------------------------------------------------+

41日前ですか。
では40日前、41日前、42日前の順番に叩いてみます。

# tmpwatch --test -umc 40d /root/
removing file /root/monthly_maintenance7.sh

# tmpwatch --test -umc 41d /root/
removing file /root/monthly_maintenance7.sh

# tmpwatch --test -umc 42d /root/
#

予想通りの展開、現在に一番近い日時で判定されました。

というわけで “-umc” を指定したときは
————————————————–
ファイルが持つ atime, mtime, ctime の中で
現在時刻に一番近い時刻を持つタイムスタンプで判定される
————————————————–
です。

実際に一括削除したいときは mtime を指定することが多いと思いますので
コイツ↓を使ってやってみます。
————————————————–
Modify: 2018-09-14 09:15:04.949783177 +0900
————————————————–

mysql> select datediff('2018-09-14', current_date());
+--------------------------------------------------------+
| datediff('2018-09-14', current_date()) |
+--------------------------------------------------------+
|                                                   -45 |
+--------------------------------------------------------+

45日前と出ました。
では “-m” だけを指定して44日前、45日前の順番で叩いてみます。

# tmpwatch --test -m 44d /root/
removing file /root/shells/monthly_maintenance7.sh

# tmpwatch --test -m 45d /root/
#

ん?様子が違いますね。
エポックタイムで計算してみますか。

# date +%s
1540756100

# date +%s -d '2018-09-14 09:15:04'
1536884104

mysql> select (1540760106 - 1536884104) / 60 / 60 / 24;
+------------------------------------------------------------------+
| (1540760106 - 1536884104) / 60 / 60 / 24 |
+------------------------------------------------------------------+
|                                       44.861134259259 |
+------------------------------------------------------------------+

現在時刻が起点になって微妙に44日前。。。
45日前になるためには4時間ほど足りないみたいです。

はい、完璧主義の方は計算してガンバッて下さい。m(_ _)m

で、あらためて前述のcron.dailyスクリプトを眺めると
・毎日1回、tmpwatchコマンドが巡回してきて
・/tmp/配下のファイルは10日経過したら
・/var/tmp/配下のファイルは30日経過したら
・粛々とバッサリ削除されるわけですね。

無闇に /tmp や /var/tmp にファイルを保存するのはやめましょう。

実績数30,000件!
サーバーやネットワークなど
ITインフラのことならネットアシストへ、
お気軽にご相談ください