我的 bash 脚本保留最后 x 个文件并删除其余文件有什么问题?

我的 bash 脚本保留最后 x 个文件并删除其余文件有什么问题?

我有这个 bash 脚本,可以按照 cron 计划很好地备份我的数据库:

#!/bin/sh

PT_MYSQLDUMPPATH=/usr/bin
PT_HOMEPATH=/home/philosop
PT_TOOLPATH=$PT_HOMEPATH/philosophy-tools
PT_MYSQLBACKUPPATH=$PT_TOOLPATH/mysql-backups
PT_MYSQLUSER=*********
PT_MYSQLPASSWORD="********"
PT_MYSQLDATABASE=*********
PT_BACKUPDATETIME=`date +%s`
PT_BACKUPFILENAME=mysqlbackup_$PT_BACKUPDATETIME.sql.gz
PT_FILESTOKEEP=14

$PT_MYSQLDUMPPATH/mysqldump -u$PT_MYSQLUSER -p$PT_MYSQLPASSWORD --opt $PT_MYSQLDATABASE | gzip -c > $PT_MYSQLBACKUPPATH/$PT_BACKUPFILENAME

问题在于,它会继续转储文件夹中的备份,而不会清理旧文件。这就是变量的作用PT_FILESTOKEEP所在。无论将此设置为多少,这就是我想要保留的备份数量。所有备份都带有时间戳,因此按名称 DESC 排序将为您提供最新的备份。

有人能帮我完成 BASH 脚本的其余部分以添加文件清理吗?我对 bash 了解不多,无法拼凑代码来完成其余部分。

答案1

首先,确保您在正确的文件夹中:

if [ -z $PT_MYSQLBACKUPPATH ]; then
 echo "No PT_MYSQLBACKUPPATH set. Exit"
 exit 1
fi
cd $PT_MYSQLBACKUPPATH
if [ $? != 0 ]; then
 echo "cd to PT_MYSQLBACKUPPATH failed. Exit"
 exit 1
fi

根据您的情况,您可以删除早于 n 的文件:

find -mtime +14 -delete

删除超过 14 天的文件。

对于您的问题,有更复杂(但绝对不是最佳)的解决方案:

# Get list of newest files. If newest files are first, use head -n 14 instead of 
# head.
files=(`ls | sort | tail -n 14`)
# Loop over all files in this folder
for i in *; do 
 preserve=0; 
 #Check whether this file is in files array:
 for a in ${files[@]}; do 
  if [ $i == $a ]; then 
   preserve=1; 
  fi; 
 done; 
 # If it wasn't, delete it (or in this case, print filename)
 if [ $preserve == 0 ]; then 
  echo $i; # test first, then change this to "rm $i"
 fi;
done

答案2

你可以尝试这个:

ls -r1 $PT_MYSQLBACKUPPATH/ | tail -n +$(($PT_FILESTOKEEP+1)) | xargs rm

ls -r1将以相反的顺序列出所有文件,每行一个文件。

tail -n +$number过滤掉列表中的前 $number-1 个文件(分别显示从 $number 开始直到最后一个的所有文件)。

xargsrm将使用标准输入中的所有文件名执行。

答案3

以下是我从这篇文章中获得的灵感:

#!/bin/bash
# Thu Jun 28 13:22:53 CEST 2012
# ${DESTDIR}/files2keep.sh
# Keep the 3 yungest files
# mra at miracleas.dk , deployed on RHEL 6.
InitValues(){
TODAY=`date +"%Y%m%d"`
NOW=`date +"%H%M"`
DESTDIR=/mnt/dbdmp
LOGFILE=?{0}-${TODAY}-${NOW}.log
}
BackupFileMaintenance(){
KEEPFILES=(`ls -lrt ${DESTDIR}/*mysqldump.sql.gz| tail -n 3| awk '{print $9}'`)
    for i in `ls -lrt ${DESTDIR}/*mysqldump.sql.gz | awk '{print $9}'`; do
    preserve=0 
    #Check whether this file is in files array:
        for a in ${KEEPFILES[@]}; do
                if [ $i == $a ]; then
                preserve=1 
                fi 
        done 
    if [ $preserve == 0 ]; then
    echo $i; # then change this to "rm -f $i" after test
    fi
    done
}
InitValues
BackupFileMaintenance
exit

答案4

抱歉重新打开这个旧帖子,但我最近遇到了类似的问题,但找不到好的解决方案。

最后我这样解决了:

cd /directory_where_things_need_removing
ls -tr1dQ * | head -n -31 | xargs rm -rf

重要的部分是 ls -tr1dQ,其中 Q 是引号,解决了空格问题,而 1 则为每行提供 1 个解决方案。head -n -31 省略了前 31 行(在我的情况下 = 1 个月)。请注意 n 之前以及要保留的行数之前的 -。在 scientific linux 6.5 上进行了测试

相关内容