Linux 在备份脚本中保留n个最新目录
我在Linux 在备份脚本中保留n个最新目录,linux,bash,unix,backup,Linux,Bash,Unix,Backup,我在/home/backup/中有存储年度备份的目录。在备份文件夹中,我们有以下目录: /home/backup/2012 /home/backup/2013 /home/backup/2014 /home/backup/2015 /home/backup/2016 /home/backup/2017 每年我都要清理数据,只保留最后三年的备份 在上述情况下,我必须删除: /home/backup/2012 /home/backup/2013 /home/backup/2014 找到要删除的目
/home/backup/
中有存储年度备份的目录。在备份文件夹中,我们有以下目录:
/home/backup/2012
/home/backup/2013
/home/backup/2014
/home/backup/2015
/home/backup/2016
/home/backup/2017
每年我都要清理数据,只保留最后三年的备份
在上述情况下,我必须删除:
/home/backup/2012
/home/backup/2013
/home/backup/2014
找到要删除的目录的最佳方法是什么?我有这个,但不起作用:
find /home/ecentrix/recording/ -maxdepth 1 -mindepth 1 -type d -ctime +1095 -exec rm -rf {} \;
你们还有别的办法吗?如果要删除目录,请键入以下命令
sudo rm-r[文件夹名称]
#在你的情况下是这样的
sudo rm-r/home/backup/2012
sudo rm-r/home/backup/2013
sudo rm-r/home/backup/2014
由于您的目录具有定义良好的整数名称,因此我仅使用bash来计算适当的目标:
mkdir -p backup/201{2..7} # just for testing
cd backup
rm -fr $(seq 2012 $(( $(date +"%Y") - 3)))
seq
生成一个从2012年到当前年份减去3的数字列表,然后将其传递到rm
以将其清除。解决方案
解释
shopt-s extglob
允许您匹配除中的文件之外的任何文件!(…)
。因此,该行表示删除/home/backup
中的任何文件,但2015
、2016
或2017
除外
rm-r-i…
中的-i
标志允许您以交互方式确认删除每个文件。如果要自动删除文件,请删除-i
动态日期
此解决方案适用于自动化(例如cron作业)
注意:备份目录中的所有文件将被删除,过去3年除外
这里有一个方法
更新答案
[dev]$ find backup/* | grep -vE "$(date '+%Y')|$(date +%Y --date='1 year ago')|$(date +%Y --date='2 year ago')" | xargs rm -rfv
removed directory: ‘backup/2012’
removed directory: ‘backup/2013’
removed directory: ‘backup/2014’
更通用的解决方案 我认为最好按降序遍历目录,然后删除第三个之后的目录。这样,当脚本一次又一次运行时,就不会有丢失目录的危险:
#!/bin/bash
backups_to_keep=3
count=0
cd /home/backup
while read -d '' -r dir; do
[[ -d "$dir" ]] || continue # skip if not directory
((++count <= backups_to_keep)) && continue # skip if we are within retaining territory
echo "Removing old backup directory '$dir'" # it is good to log what was cleaned up
echo rm -rf -- "$dir"
done < <(find . -maxdepth 1 -name '[2-9][0-9][0-9][0-9]' -type d -print0 | sort -nrz)
将cd/home/backup
限制在该目录中以提供额外的安全性rm-rf
提供与全局匹配的顶级目录find-maxdepth 1-名称“[2-9][0-9][0-9][0-9]”-键入d
确保更新的目录排在第一位,sort-nrz
处理-z
find的以null结尾的输出-print0
- 此解决方案不硬编码年份-它只是假设要删除的目录以数字排序的方式命名
- 它对备份目录中存在的任何其他文件或目录具有弹性
- 如果脚本反复运行,则不会产生任何副作用
- 这可以很容易地扩展以支持备份目录的不同命名约定-只需更改glob表达式即可
find /home/backup/2* -maxdepth 1 | sort -r | awk "NR>3" | xargs rm -rf
这是怎么回事
find test01/2* -maxdepth 1 | sort -r | awk "NR>4" | xargs echo rm -rf
我使用了NR>4而不是NR>3(如您所愿),因为NR>4表明我们正在选择从列表中删除多少行,因此没有删除
以下是我得到的:
上面的第二个到最后一个命令更改了最后一个阶段,使其不响应将要执行的操作,而是实际执行
我在脚本中有一个转储的原始副本,因为我在我的一些服务器上使用它,您可以在这里查看它:
成功所必需的
这种方法取决于find命令生成的内容的字母顺序。在我的例子中,我使用的是,当它们按字母顺序排列时,完全有助于进行固有的日期排序。您的YYYY类型日期完全符合条件
附加安全
我建议您将备份更改为存储为tar存档。然后您可以将rm-rf更改为简单的rm。这是一个安全得多,但不是傻瓜证明。不管怎样,您真的应该作为一个专用的非特权用户来运行它(在我看来,对于任何调用delete的脚本,您都应该这样做)
要知道,如果你从
find /home/backup
然后对xargs的调用将包括/home/backup本身,这将是一场灾难,因为它也会被删除。因此,您必须在该路径中进行搜索。而不是用下面的话来称呼它会起作用:
find /home/backup/*
我上面给出的2*只是某种程度上限制搜索操作的一种方式
担保
没有;这是互联网。小心。对事情进行严格的测试以说服自己。另外,也可以获取一些脱机备份
最后—我以前将此作为答案发布,但犯了一个致命的错误,即表示基于/home/backup和非/home/backup/*或/home/backup/2*的find命令。这导致/home/backup也被发送删除,这将是一场灾难。这是一个非常小的区别,我已经试图弄清楚上面。我已经删除了之前的答案,并将其替换为此答案。假设只有3个旧目录需要删除。您将如何添加
find test01/2* -maxdepth 1 | sort -r | awk "NR>4" | xargs echo rm -rf
find /home/backup
find /home/backup/*