我无法获得以下脚本(这是更大的备份脚本的一部分)才能正常工作:
BACKUPDIR=/BACKUP/db01/physical/incremental # Backups base directory
FULLBACKUPDIR=$BACKUPDIR/full # Full backups directory
INCRBACKUPDIR=$BACKUPDIR/incr # Incremental backups directory
KEEP=5 # Number of full backups (and its incrementals) to keep
...
FIRST_DELETE=`expr $KEEP + 1` # add one to the number of backups to keep, this will be the first deleted
FILE0=`ls -ltr $FULLBACKUPDIR | awk '{print $9}' | tail -$FIRST_DELETE | head -1` # search for the first backup to be deleted
...
find $FULLBACKUPDIR -maxdepth 1 -type d ! -newer $FULLBACKUPDIR/$FILE0 -execdir echo "removing: "$FULLBACKUPDIR/$(basename {}) \; -execdir bash -c 'rm -rf $FULLBACKUPDIR/$(basename {})' \; -execdir echo "removing: "$INCRBACKUPDIR/$(basename {}) \; -execdir bash -c 'rm -rf $INCRBACKUPDIR/$(basename {})' \;
所以这个查找工作正常,它本身会输出这样的东西:
/BACKUPS/db01/physical/incremental/full/2013-08-12_17-51-28
/BACKUPS/db01/physical/incremental/full/2013-08-12_17-51-28
/BACKUPS/db01/physical/incremental/full/2013-08-12_17-25-07
我想要的是-exec回显显示正在删除的内容的行,然后从两个目录中删除该文件夹。
我尝试了各种方法来获取基本名称,但似乎没有任何工作。我明白了:
removing: /BACKUPS/mysql/physical/incremental/full/"/BACKUPS/mysql/physical/incremental/full/2013-08-12_17-51-28"
removing: /BACKUPS/mysql/physical/incremental/incr/"/BACKUPS/mysql/physical/incremental/full/2013-08-12_17-51-28"
removing: /BACKUPS/mysql/physical/incremental/full/"/BACKUPS/mysql/physical/incremental/full/2013-08-12_17-25-07"
当然文件夹不会被删除,因为它们不存在,只是因为-f选项而无声地失败。如果我删除-f,我会在每个rm上收到“无法找到”错误。
我如何做到这一点?由于备份和部分备份可能存储在不同的存储系统中,因此我真的需要能够获取文件夹名称以便在任何已知路径中使用。
答案 0 :(得分:0)
首先运行$(basename {})
,将removing: "$INCRBACKUPDIR/$(basename {})
设为removing: "$INCRBACKUPDIR/{}
,然后替换为{}
。
绕过它的方法可能是将它传递给bash:
-exec echo "echo \"removing: \\\"$INCRBACKUPDIR/\$(basename {})\\\"\" | bash" \;
答案 1 :(得分:0)
这里有很多破碎。
$()
ls
(!)ls -l
(!!!)所有绝对需要为了改善这一点,-exec bash
正确,例如。
-execdir bash -c 'filepath="$1" ; base=$(basename "$filepath") ; echo use $filepath and $base here' -- {} \;
但是这样呢:
#!/usr/bin/env bash
backup_base=/BACKUP/db01/physical/incremental
full_backup="$backup_base"/full
incremental_backup="$backup_base"/incr
keep=5
rm=echo
let n=0
while IFS= read -r -d $'\0' line ; do
file="${line#* }"
if [[ $n -lt $keep ]] ; then
let n=n+1
continue
fi
base=$(basename "$file")
echo "removing: $full_backup/$base"
"$rm" -rf -- "$full_backup"/"$base"
echo "removing: $incremental_backup/$base"
"$rm" -rf -- "$incremental_backup"/"$base"
done < <(find "$full_backup" -maxdepth 1 -printf '%T@.%p\0' 2>/dev/null | sort -z -r -n -t. -k1,2)
直接在备份目录下迭代文件和目录,并跳过最新的5个。从与其余名称匹配的完整和增量目录文件中删除。
这是一个基本上安全的版本,当然除了定时攻击。
我已将rm
定义为echo
以避免意外删除; 一旦你确定它是正确的,就把它交换回rm
进行实际删除。