首页 > 解决方案 > 用于删除旧备份文件的现有 bash 脚本 - 它是如何工作的?

问题描述

我是脚本的初学者。我有一些关于旧脚本的问题,它应该删除旧的备份文件。

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。但是下面的逻辑我理解不正确。

标签: bashshellosx-yosemite

解决方案


这个答案不完整,因为我缺乏信息。此外,它应该完成的任务似乎过于复杂。


下面的循环处理 /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 
  1. stat在文件上调用f

    -f format 使用指定的格式显示信息。有关有效格式的说明,请参阅格式部分。

    -t timefmt 使用指定格式显示时间戳。此格式直接传递给strftime (3)。

    • 根据手册页的FORMATS部分,是和%Sm的组合,分别代表 1)“[最后]时间文件 [...]被修改”()和 2)格式化,“如果适用,应该是字符串格式" ( ,这里应该是这种情况)。SmmS
    • 根据strftime%m %V %d的手册页,以十进制数表示月份、年份中的星期数和月份中的日期。
  2. 输出read存储在变量中MONTH WEEKDAY-s代表静默模式

此时,您有月份、一年中的周数和文件被修改时的月份中的日期。

接下来最难的部分:

  • 如果之前处理过的文件的修改天数等于当前处理过的文件天数,则检查是否在-mtime一周前被修改过()( KEEP_FULL=7);如果是这样,删除它(f传递给rmwith xargs):

    if [ $DAY -eq $LAST_DAY ]; then
        find $f -mtime +$KEEP_FULL | xargs rm 
    fi
    
  • 否则,如果之前处理过的文件(呼吸)修改年份的周数等于当前处理过的文件一,则检查是否在两周前修改过(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循环标准输入的第一个输出文件的顺序。


推荐阅读