Reputation: 688
I'm a total beginner with scripts. I have some questings regarding an old script, which should delete old backup files.
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
Could someone explain (for dummies) what happens within the while-loop? I understand that for each file within the folder the information (day, week, month of creation) is written into $MONTH $WEEK $DAY. But the following logic I don't understand correctly.
Upvotes: 1
Views: 495
Reputation: 6394
This answer won't be complete because I lack informations. Also It seems overly complex for the task it should do.
The loop below process all files under /Volumes/path and stores them in the variable f
.
find $DB_FULL_PATH -type f| while read f; do
# [...]
done
For each file f
, this command is first performed:
< <(stat -f %Sm -t "%m %V %d" $f) read -s MONTH WEEK DAY
stat
is invoked on the file f
-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).
%Sm
is the combination of S
and m
, which stand respectively for 1) "the [last] time file was [...] modified" (m
) and 2) formatted, "if applicable, should be in string format" (S
, it should be the case here).%m %V %d
stand for the month, the week number of the year and the day of the month as a decimal numberread
and stored in variables MONTH
WEEK
and DAY
(-s
stands for silent mode)At this point, you have the month, the week number of the year and the day of the month of the time the file was modifed.
Next the hardest part:
If the day of modification of the previously processed file equals the current processed file one, then check if it was modified (-mtime
) one week ago (KEEP_FULL
=7) ; if so, delete it (f
is passed to rm
with xargs
):
if [ $DAY -eq $LAST_DAY ]; then
find $f -mtime +$KEEP_FULL | xargs rm
fi
Otherwise, if the week number of the year of modification of the previously processed file (breathes) equals the current processed file one, then check if it was modified two weeks ago (KEEP_DAILY
=14) ; if so, delete it:
else if [ $WEEK -eq $LAST_WEEK ]; then
find $f -mtime +$KEEP_DAILY | xargs rm
Otherwise, if the month of modification of the previously processed file (sips) equals the current processed file one, then check if it was modified 30 days ago (KEEP_WEEKLY
=30) ; if so, delete it:
else if [ $MONTH -eq $LAST_MONTH ]; then
find $f -mtime +$KEEP_WEEKLY | xargs rm
fi fi fi
Retrieve the month, the week and the day of the month of the current file to process the next one with them (will be used as parts of the modification time of said "previously processed" file):
export LAST_DAY=$DAY
export LAST_WEEK=$WEEK
export LAST_MONTH=$MONTH
done
That said, to understand why such comparisons are performed, you need to know the order the first find
outputs files injected to the standard input of the while
loop.
Upvotes: 1