用于删除旧备份文件的现有 bash 脚本 - 它是如何工作的?
existing bash script for deleting old backup files - how does it work?
我完全是脚本初学者。我有一些关于旧脚本的问题,应该删除旧的备份文件。
KEEP_FULL=7
KEEP_DAILY=14
KEEP_WEEKLY=30
DB_FULL_PATH=/Volumes/path
LAST_DAY=0
LAST_WEEK=0
LAST_MONTH=0
find $DB_FULL_PATH -type f| while read f; do
< <(stat -f %Sm -t "%m %V %d" $f) read -s MONTH WEEK DAY
if [ $DAY -eq $LAST_DAY ]; then
find $f -mtime +$KEEP_FULL | xargs rm
else if [ $WEEK -eq $LAST_WEEK ]; then
find $f -mtime +$KEEP_DAILY | xargs rm
else if [ $MONTH -eq $LAST_MONTH ]; then
find $f -mtime +$KEEP_WEEKLY | xargs rm
fi fi fi
export LAST_DAY=$DAY
export LAST_WEEK=$WEEK
export LAST_MONTH=$MONTH
done
有人可以解释一下(傻瓜)while 循环中发生了什么吗?
我知道对于文件夹中的每个文件,信息(创建日、周、月)都写入 $MONTH $WEEK $DAY。
但是下面的逻辑我没有理解正确。
这个回答不会完整,因为我缺少信息。此外,它应该完成的任务似乎过于复杂。
下面的循环处理 /Volumes/path 下的所有文件并将它们存储在变量 f
.
中
find $DB_FULL_PATH -type f| while read f; do
# [...]
done
对于每个文件f
,首先执行此命令:
< <(stat -f %Sm -t "%m %V %d" $f) read -s MONTH WEEK DAY
stat
在文件 f
上调用
- 根据 stat (OSX) 的 man page:
-f
format Display information using the specified format. See the FORMATS section for a description of valid formats.
-t
timefmt Display timestamps using the specified format. This format is passed directly to strftime(3).
- 根据手册页的FORMATS部分,
%Sm
是S
和m
的组合,分别代表1) “[上次] 时间文件是 [...] 修改的 ” (m
) 和 2) 格式化,“如果适用,应该是字符串格式” ( S
,这里应该是这样的)。
- 根据strftime的手册页,
%m %V %d
代表月,一年中的周数和一个月中的第几天作为十进制数
- 输出为
read
并存储在变量MONTH
WEEK
和DAY
中(-s
代表silent mode)
此时,您有月、一年中的周数和日文件修改时间的月份。
接下来是最难的部分:
如果之前处理文件的修改日期等于当前处理文件的日期,则检查是否在(-mtime
)一周前(KEEP_FULL
= 7);如果是这样,删除它(f
通过 xargs
传递给 rm
):
if [ $DAY -eq $LAST_DAY ]; then
find $f -mtime +$KEEP_FULL | xargs rm
fi
否则如果之前处理的文件修改年份的周数(breathes)等于当前处理的文件一,则检查是否两周前修改过(KEEP_DAILY
=14);如果是,删除它:
else if [ $WEEK -eq $LAST_WEEK ]; then
find $f -mtime +$KEEP_DAILY | xargs rm
否则如果之前处理的文件修改月份(sips)等于当前处理的文件一,则检查是否修改30天之前 (KEEP_WEEKLY
=30) ;如果是,删除它:
else if [ $MONTH -eq $LAST_MONTH ]; then
find $f -mtime +$KEEP_WEEKLY | xargs rm
fi fi fi
检索当前文件的月份、星期和月份的日期以处理下一个文件(将用作所述“先前处理”文件的修改时间的一部分):
export LAST_DAY=$DAY
export LAST_WEEK=$WEEK
export LAST_MONTH=$MONTH
done
也就是说,要理解为什么要执行这样的比较,您需要知道第一个 find
输出文件注入到 while
循环的标准输入的顺序。
我完全是脚本初学者。我有一些关于旧脚本的问题,应该删除旧的备份文件。
KEEP_FULL=7
KEEP_DAILY=14
KEEP_WEEKLY=30
DB_FULL_PATH=/Volumes/path
LAST_DAY=0
LAST_WEEK=0
LAST_MONTH=0
find $DB_FULL_PATH -type f| while read f; do
< <(stat -f %Sm -t "%m %V %d" $f) read -s MONTH WEEK DAY
if [ $DAY -eq $LAST_DAY ]; then
find $f -mtime +$KEEP_FULL | xargs rm
else if [ $WEEK -eq $LAST_WEEK ]; then
find $f -mtime +$KEEP_DAILY | xargs rm
else if [ $MONTH -eq $LAST_MONTH ]; then
find $f -mtime +$KEEP_WEEKLY | xargs rm
fi fi fi
export LAST_DAY=$DAY
export LAST_WEEK=$WEEK
export LAST_MONTH=$MONTH
done
有人可以解释一下(傻瓜)while 循环中发生了什么吗? 我知道对于文件夹中的每个文件,信息(创建日、周、月)都写入 $MONTH $WEEK $DAY。 但是下面的逻辑我没有理解正确。
这个回答不会完整,因为我缺少信息。此外,它应该完成的任务似乎过于复杂。
下面的循环处理 /Volumes/path 下的所有文件并将它们存储在变量 f
.
find $DB_FULL_PATH -type f| while read f; do
# [...]
done
对于每个文件f
,首先执行此命令:
< <(stat -f %Sm -t "%m %V %d" $f) read -s MONTH WEEK DAY
stat
在文件f
上调用- 根据 stat (OSX) 的 man page:
-f
format Display information using the specified format. See the FORMATS section for a description of valid formats.-t
timefmt Display timestamps using the specified format. This format is passed directly to strftime(3).- 根据手册页的FORMATS部分,
%Sm
是S
和m
的组合,分别代表1) “[上次] 时间文件是 [...] 修改的 ” (m
) 和 2) 格式化,“如果适用,应该是字符串格式” (S
,这里应该是这样的)。 - 根据strftime的手册页,
%m %V %d
代表月,一年中的周数和一个月中的第几天作为十进制数
- 输出为
read
并存储在变量MONTH
WEEK
和DAY
中(-s
代表silent mode)
此时,您有月、一年中的周数和日文件修改时间的月份。
接下来是最难的部分:
如果之前处理文件的修改日期等于当前处理文件的日期,则检查是否在(
-mtime
)一周前(KEEP_FULL
= 7);如果是这样,删除它(f
通过xargs
传递给rm
):if [ $DAY -eq $LAST_DAY ]; then find $f -mtime +$KEEP_FULL | xargs rm fi
否则如果之前处理的文件修改年份的周数(breathes)等于当前处理的文件一,则检查是否两周前修改过(
KEEP_DAILY
=14);如果是,删除它:else if [ $WEEK -eq $LAST_WEEK ]; then find $f -mtime +$KEEP_DAILY | xargs rm
否则如果之前处理的文件修改月份(sips)等于当前处理的文件一,则检查是否修改30天之前 (
KEEP_WEEKLY
=30) ;如果是,删除它:else if [ $MONTH -eq $LAST_MONTH ]; then find $f -mtime +$KEEP_WEEKLY | xargs rm fi fi fi
检索当前文件的月份、星期和月份的日期以处理下一个文件(将用作所述“先前处理”文件的修改时间的一部分):
export LAST_DAY=$DAY export LAST_WEEK=$WEEK export LAST_MONTH=$MONTH done
也就是说,要理解为什么要执行这样的比较,您需要知道第一个 find
输出文件注入到 while
循环的标准输入的顺序。