2017-06-29 36 views
0

我使用rsync将我们的卫星服务器的照片复制到主服务器中。所以执行它的脚本基本上是从PC连接到PC并执行rsyncrsync只有年龄小于xy天的文件

我一直在尝试使用find来确定年龄小于xy天的文件(这将是天,但数量可能会有所不同)。使用--files-from=<()指定文件,但在某些机器上命令find /var/dav/davserver/ -mtime -3 -type f -exec basename {} \;非常慢,甚至使rsync超时。它们也是服务器,所以每隔几分钟运行一次这个命令会花费太多的处理器能力,我不想拿走它们。

第二个问题是利用我们存储这些文件的方式,在/var/dav/davserver/year/month/day/目录下。然而,当我开始研究它时,我意识到我需要编写相当多的代码来处理几个月和几年的时间,甚至更多的时间不是固定的(可能超过31天,因此这个脚本可能需要运行几个月)。

所以我想知道是否没有一些更简单的方法如何实现这个没有杀死源PC处理器或写一个全新的库来照顾所有月/年结束?


编辑:

我已经准备脚本生成我的文件的路径。我所做的,就是我离开两个月处理端/年date ..

#!/bin/bash 

DATE_now=`date +"%Y-%m-%d"` 
DATE_end=`date -d "-$1 days" +"%Y-%m-%d"` 

echo "Date now: $DATE_now | Date end: $DATE_end" 

start_d=`date +%s` 
end_d=`date -d "-$1 days" +%s` 

synced_day=$DATE_now 
synced_day_s=$start_d 
daycount=1 

echo "" > /tmp/$2_paths 

while [ $synced_day_s -ge $end_d ]; do 
    DAY=$(date -d "$synced_day" '+%d') 
    MONTH=$(date -d "$synced_day" '+%m') 
    YEAR=$(date -d "$synced_day" '+%Y') 

    SYNC_DIR="/var/dav/davserver/$YEAR/$MONTH/$DAY/**" 
    echo "Adding day ($synced_day) directory: \"$SYNC_DIR\" to synced paths | Day: $daycount" 
    echo $SYNC_DIR >> /tmp/$2_paths 

    synced_day=$(date -d "$synced_day -1 days" +"%Y-%m-%d") 
    synced_day_s=$(date -d "$synced_day" +%s) 
    daycount=$((daycount+1)) 
done 

,并使用它,不仅仅是提取所需的信息倒计时天。这个剧本给我目录列表进行rsync:

[email protected]:~/bash_devel$ bash date_extract.sh 8 Z00163 
Date now: 2017-06-29 | Date end: 2017-06-21 
Adding day (2017-06-29) directory: "/var/dav/davserver/2017/06/29/**" to synced paths | Day: 1 
Adding day (2017-06-28) directory: "/var/dav/davserver/2017/06/28/**" to synced paths | Day: 2 
Adding day (2017-06-27) directory: "/var/dav/davserver/2017/06/27/**" to synced paths | Day: 3 
Adding day (2017-06-26) directory: "/var/dav/davserver/2017/06/26/**" to synced paths | Day: 4 
Adding day (2017-06-25) directory: "/var/dav/davserver/2017/06/25/**" to synced paths | Day: 5 
Adding day (2017-06-24) directory: "/var/dav/davserver/2017/06/24/**" to synced paths | Day: 6 
Adding day (2017-06-23) directory: "/var/dav/davserver/2017/06/23/**" to synced paths | Day: 7 
Adding day (2017-06-22) directory: "/var/dav/davserver/2017/06/22/**" to synced paths | Day: 8 
[email protected]:~/bash_devel$ cat /tmp/Z00163_paths 

/var/dav/davserver/2017/06/29/** 
/var/dav/davserver/2017/06/28/** 
/var/dav/davserver/2017/06/27/** 
/var/dav/davserver/2017/06/26/** 
/var/dav/davserver/2017/06/25/** 
/var/dav/davserver/2017/06/24/** 
/var/dav/davserver/2017/06/23/** 
/var/dav/davserver/2017/06/22/** 
[email protected]:~/bash_devel$ 

但是,现在,我使用这个列表的问题,我一直在试图使用--include--exclude命令很多组合都--include-files--include-from但我只获得2个结果:要么一切正在被rsynced,要么什么都没有。

+0

Rsync有一个'--ignore-existing'选项,所以它只复制新文件。 – pikand

+0

是的,但在卫星服务器上可能有大约3年的数据(在某些情况下)。不过,我只想在主服务器上只保存30天的数据。 – rRr

+0

你可以先运行你的'find'命令,通过管道连接到一个文件,然后才启动'rsync'命令?甚至可以传送到'rsync'中。只是不在子shell中。 –

回答

1

既然你已经按日期排序(在目录)的文件,它很容易和有效,只是rsync这些目录:

#!/bin/bash 
maxage="45" # in days, from today 
for ((d=0; d<=maxage; d++)); do 
    dir="/var/dav/davserver/$(date -d "-$d day" +"%Y/%m/%d")" 
    rsync -avrz server:"$dir" localdir 
done 

我们使用date计算today - x days和遍历所有天0到您的maxage

编辑:使用算术for循环而不是遍历GNU seq范围。

+0

是的,这是解决方案,但是,问题是,我想的rsync还删除了同步yrday和今天过时的文件 – rRr

+0

你可以运行一个类似的清理脚本只是删除本地不同于'之前的所有目录'maxage'' days:''for d in $(seq“$ maxage”“365”);做...''。 – randomir

+0

* grumble * re:'seq'(不是bash的一部分,不是POSIX标准化的)。 (for((d = 0; d <= 365; d ++)); do ...'保证在任何地方工作bash,而'i = 0; while [“$ i”-le 365];做...; i = $((i + 1));完成“保证可以在所有POSIX shell上运行。 –

0

所以,我已经解决了它的组合:

脚本根据实际日期生成路径。详细信息显示在我的初始职位编辑中。它仅使用date来完成前几天,并管理月和年结束。并从这些日期生成路径。然而radomir的解决方案更简单,所以我会使用它。 (它与我的基本相同,只是简单的写下来)。

比我已经使用--include-files=/tmp/files_list-r又如-r又一个参数的组合,以正确使用这个路径列表。 (它仅复制空目录,而-r而且什么都不要,如果我用的--include-from代替--include-files。)

最终rsync命令是:

rsync --timeout=300 -Sazrv --force --delete --numeric-ids --files-from=/tmp/date_paths [email protected]:/var/dav/davserver/ /data/snapshots/ 

但是这个解决方案是不删除旧文件我尽管有--delete的说法。可能需要为它制作额外的脚本。

+0

无需临时文件(和你避免接触到符号链接攻击),如果你使用一个进程替换来生成列表。 ('--from0 --files-从= <(找到 “$ PATH” -mtime -7 -print0')或者,至少,使用'mktemp'生成一个唯一的临时文件名 - 这样攻击者就可以”牛逼创建'/ tmp'一个符号链接(这是,毕竟,世界可写目录)的文件,他们希望你删除。 –