【问题标题】:Bash Script for deleting old backup files用于删除旧备份文件的 Bash 脚本
【发布时间】:2014-12-02 08:44:22
【问题描述】:

每天晚上我的服务器都会为每个 mysql 数据库创建备份。所有这些文件都保存在 /backup/mysql/2014-11-28 之类的文件夹中。在过去的几个月里,该目录中存储了很多文件夹和文件,我想减少这种情况。

因此,我需要一个 bash 脚本来删除给定目录中的每个文件夹,除了本月创建的每个文件夹(不是过去 30 天,而是实际月份)和每周的一次备份(例如备份从周日开始)。由于我不知道如何举办周日聚会,我决定保留 07 日、14 日、21 日和 28 日的备份会更简单。

#!/bin/bash
in_array() {
local haystack=${1}[@]
local needle=${2}
for i in ${!haystack}; do
    if [[ ${i} == ${needle} ]]; then
        return 0
    fi
done
return 1
}

YEAR=`date +%Y`
LASTYEAR=`date +%Y -d "1 year ago"`
MONTH=`date +%m`
DAYS="07 14 21 28"
for i in $( ls ); do
BACKUP_YEAR=$(echo "${i}" | cut -d'-' -f1)
BACKUP_MONTH=$(echo "${i}" | cut -d'-' -f2)
BACKUP_DAY=$(echo "${i}" | cut -d'-' -f3)

DELETE=false

if [[ "$BACKUP_YEAR" == "$YEAR" ]]; then
    if [[ "$BACKUP_MONTH" != "$MONTH" ]]; then
            if [ $(in_array $DAYS "$BACKUP_DAY") ]; then
                DELETE=true
            fi
    fi
fi
if [[ "$BACKUP_YEAR" == "$LASTYEAR" ]]; then
    if [[ "$BACKUP_DAY" != ${DAYS[0]} ]]; then
        DELETE=true
    fi
fi
if [ "$DELETE" = true ] ; then
    #OUTPUT=`rm -v -R $i`
    echo $i
fi
done

第二部分(前一年的备份)运行良好,但第一部分(今年的备份)不起作用,我不知道为什么。我在这个网站上找到了这个函数,但我猜我的调用是错误的。

编辑:我现在使用的代码:

#!/bin/bash
read YEAR MONTH <<<$(date "+%Y %m")
LASTYEAR=$(( YEAR-1 ))
DAYS=" 07 14 21 28 "

for fn in $( ls )
do
    if   ([ "${fn:0:4}" = "$YEAR" ] &&
    [ "${fn:5:2}" != "$MONTH" ] &&
    [ "${DAYS/ ${fn:8:2} /}" = "$DAYS" ]) || ([ "${fn:0:4}" = "$LASTYEAR" ] &&
    [ "${fn:8:2}" != ${DAYS:1:2} ])
    then
         #OUTPUT=`rm -v -R $fn`
         echo "$fn"
   fi
done

【问题讨论】:

  • 嗨,大卫。请回答自己以下问题:“第二部分”和“第一部分”之间的主要区别是什么? --in_array函数的使用。
  • in_array 07 14 21 28 19 可能是传递给in_array 函数的参数示例。他们是对的吗?

标签: bash backup


【解决方案1】:
#!/bin/bash
read YEAR MONTH <<<$(date "+%Y %m")
LASTYEAR=$(( YEAR-1 ))
DAYS=" 07 14 21 28 "

for fn in $( ls )
do
     DELETE=false

     if   [ "${fn:0:7}" = "$YEAR-$MONTH" ] &&
          [ "${DAYS/ ${fn:8:2} /}" != "$DAYS" ]
     then
          DELETE=true
     elif [ "${fn:0:4}" = "$LASTYEAR" ] &&
          [ "${fn:8:2}" != ${DAYS:1:2} ]
     then
          DELETE=true
     fi

     if [ "$DELETE" = true ]
     then
          #OUTPUT=`rm -v -R $fn`
          echo "$fn"
     fi
done

假设文件名与以下日期格式YYYY-MM-DD 匹配,例如2014-03-27,则表达式${fn:0:7} 将是2014-03; ${fn:8:2} 将是 27; ${fn:0:4} 将是 2014。

阅读有关 parameter expansion 的 bash 手册页。

表达式${DAYS/ ${fn:8:2} /} 从DAYS 列表中找到的文件名(由空格包裹)检查日期。相当于echo "${DAYS}" | grep -q "${BACKUP_DAY}"。

注意:可以减少for 循环内的命令(通过|| 加入if 和elif 并删除DELETE 变量检查和DELETE 变量本身)但我决定保留原始脚本的外观。

【讨论】:

  • 您好,感谢您的帮助。效果很好。我实际上是根据你的建议缩短了它。我编辑了我的原始帖子以显示我现在使用的代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-17
  • 2021-01-22
  • 2014-07-23
  • 2015-05-27
  • 1970-01-01
  • 2011-04-06
相关资源
最近更新 更多