2017-06-29 16 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'一個符號鏈接(這是,畢竟,世界可寫目錄)的文件,他們希望你刪除。 –