列出所有7天前的文件
比如,日志备份脚本,保留7份(不算当天的那一份),当天的备份生成完毕之后,要清理七天之前的备份。
# 目录 /bak/
bak-20200101.tgz
bak-20200102.tgz
bak-20200103.tgz
bak-20200104.tgz
bak-20200105.tgz
bak-20200106.tgz
bak-20200107.tgz
bak-20200108.tgz
bak-20200109.tgz
bak-20200110.tgz
如果当天是 bak-20200110.tgz,那么期望找出 bak-20200101.tgz 和 bak-202001202.tgz 并删除。
(假设他们的名字都对应文件生成日期)。
find bak -daystart -mtim +7 -print -delete
生成 16 个文件
mkdir bak && cd bak
total=6
for i in $(seq 0 $((max-1))); do
# 当前时间
dt=$(date -Is -d $(date +%F -d "today - $i day")T00:10:00+0800)
file=bak-$(date +%Y%m%d -d "$dt")-b.tgz
touch -d $dt $file
dt=$(date -Is -d $(date +%F -d "today -$i day")T23:50:00+0800)
file=bak-$(date +%Y%m%d -d "$dt")-a.tgz
touch -d $dt $file
done
$ ls -l --sort=t --time-style=full-iso
总用量 0
-rw-rw-r-- 1 work work 0 2022-04-07 23:50:00.000000000 +0800 bak-20220407-a.tgz
-rw-rw-r-- 1 work work 0 2022-04-07 00:10:00.000000000 +0800 bak-20220407-b.tgz
-rw-rw-r-- 1 work work 0 2022-04-06 23:50:00.000000000 +0800 bak-20220406-a.tgz
-rw-rw-r-- 1 work work 0 2022-04-06 00:10:00.000000000 +0800 bak-20220406-b.tgz
-rw-rw-r-- 1 work work 0 2022-04-05 23:50:00.000000000 +0800 bak-20220405-a.tgz
-rw-rw-r-- 1 work work 0 2022-04-05 00:10:00.000000000 +0800 bak-20220405-b.tgz
-rw-rw-r-- 1 work work 0 2022-04-04 23:50:00.000000000 +0800 bak-20220404-a.tgz
-rw-rw-r-- 1 work work 0 2022-04-04 00:10:00.000000000 +0800 bak-20220404-b.tgz
-rw-rw-r-- 1 work work 0 2022-04-03 23:50:00.000000000 +0800 bak-20220403-a.tgz
-rw-rw-r-- 1 work work 0 2022-04-03 00:10:00.000000000 +0800 bak-20220403-b.tgz
-rw-rw-r-- 1 work work 0 2022-04-02 23:50:00.000000000 +0800 bak-20220402-a.tgz
-rw-rw-r-- 1 work work 0 2022-04-02 00:10:00.000000000 +0800 bak-20220402-b.tgz
-rw-rw-r-- 1 work work 0 2022-04-01 23:50:00.000000000 +0800 bak-20220401-a.tgz
-rw-rw-r-- 1 work work 0 2022-04-01 00:10:00.000000000 +0800 bak-20220401-b.tgz
测试,观察
[work@cdh03 bak]$ find . -mtime 0
.
./bak-20220407-b.tgz
./bak-20220406-a.tgz
[work@cdh03 bak]$ find . -mtime 0
.
./bak-20220407-b.tgz
./bak-20220406-a.tgz
[work@cdh03 bak]$ find . -mtime 1
./bak-20220406-b.tgz
./bak-20220405-a.tgz
[work@cdh03 bak]$ find . -daystart -mtime 0
.
./bak-20220407-b.tgz
./bak-20220407-a.tgz
[work@cdh03 bak]$ find . -daystart -mtime 1
./bak-20220406-b.tgz
./bak-20220406-a.tgz
总结
根据时间测试的含义,有如下规律,
find bak -daystart -mtime n
n=0, 当天(00:00~23:59:59)
n=1,昨天(00:00~23:59:59)
所以,若每天执行一次备份,不算今天的这一份,则要保留 n 个备份,执行的命令是
find bak -daystart -mtime +n -delete
注意,其中的 -daystart 是必须的,且必须在 -mtime 之前。
如果不加 -daystart,则 -mtime +n 会保留的是 n 或 n+1 份,具体来说,假设当前时间是 hh:mm,则
若第 n+1 份的时间在 [00:00, hh:mm),就会被删除,时间在 [hh:mm, 23:59:59),会被保留。
而使用了 -daystart 则相当于把 hh:mm 置为 23:59:59
.
PS: 这么看,这个选项明明叫做 -dayend 更合适。
也可以理解为把 mtime 的时分秒置零,即 mtime = strftime(mtime, "%Y-%m-%d 00:00:00");
PS:这么看,-daystart 正好。