Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 在备份脚本中保留n个最新目录_Linux_Bash_Unix_Backup - Fatal编程技术网

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
这是怎么回事
  • 生成以“2”开头的文件名列表,仅在/home/backup下/

  • 按字母顺序将列表按相反顺序排序

  • 使用AWK筛选列表中的行数。NR指定反向排序的行数。您可以将3更改为您希望保留多少行。所以,如果你只想要最近两年,把3改成2。如果您希望保留最新的10个,请将其设置为“NR>10”

  • 将结果列表附加到命令“rm-rf”中

  • 作为专用用户运行,以确保安全 这里的危险是我建议使用rm-rf。这是有风险的。如果出现问题,您可以删除要保留的内容。我只通过一个只有删除备份文件权限的专用用户调用这些命令来降低这种风险

    功绩 这种方法的优点是,当您将它放入cron作业并随着时间的推移,它将继续只保留最新的几个目录。所以,我认为这是你的问题的一般解决方案。 示范 为了测试这一点,我创建了一个测试目录,其中包含所有与您相同的目录。我修改它只是为了看看最后会执行什么,所以我尝试:

    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/*