rsync:同步資料夾,但在目標中保留額外文件

rsync:同步資料夾,但在目標中保留額外文件

我正在開始使用rsync它並嘗試使用它來保持本地系統上的兩個資料夾同步。我有一個來源資料夾,其內容隨著時間的推移而變化(一些文件被添加,一些文件被更改,一些被刪除)和一個目標資料夾,我希望它幾乎成為源的鏡像。所以我嘗試使用 rsync 像這樣:

rsync -a --delete "${source_dir}" "${target_dir}";

這確實使目標的內容與來源的內容完全相同。但是,我希望能夠將一些檔案新增至目標而不是來源,但我不希望每次執行 rsync 時都刪除它們。另一方面,曾經同步但後來在來源中刪除的檔案仍應刪除。

有沒有辦法做到這一點,而不必更改我想要排除的每個文件的命令?

更新:我應該提一下,我並不局限於 rsync。如果另一個程式可以完成工作,那也很好。我只是嘗試使用 rsync 來解決這個問題。

答案1

rsync有一個名為--exclude-fromoption 的選項,它允許您建立一個文件,其中包含要排除的任何文件的清單。每當您想要新增新的排除項或刪除舊的排除項時,您都可以更新此檔案。

如果您在新命令中建立排除文件,/home/user/rsync_exclude則為:

rsync -a --delete --exclude-from="/home/user/rsync_exclude" "${source_dir}" "${target_dir}"

建立排除清單檔案時,應將每個排除規則放在單獨的行上。排除項與您的來源目錄相關。如果您的/home/user/rsync_exclude檔案包含以下選項:

secret_file
first_dir/subdir/*
second_dir/common_name.*
  • secret_file在來源目錄中呼叫的任何檔案或目錄都將被排除。
  • 中的任何文件都${source_dir}/first_dir/subdir將被排除,但空版本subdir將被同步。
  • ${source_dir}/second_dir任何帶有前綴的文件common_name.都將被忽略。所以等等common_name.txtcommon_name.jpg

答案2

既然你提到:我不限於rsync:

維護鏡像的腳本,允許向目標添加額外的文件

下面的腳本完全按照您的描述進行操作。

該腳本可以運行在冗長的mode(在腳本中設定),它將輸出備份(鏡像)的進度。不用說,這也可以用於記錄備份:

詳細選項

在此輸入影像描述


這個概念

1. 第一次備份時,腳本:

  • 建立一個檔案(在目標目錄中),其中列出所有檔案和目錄;.recentfiles
  • 建立目標目錄中所有檔案和目錄的精確副本(鏡像)

2.上、下等備份

  • 該腳本比較文件的目錄結構和修改日期。來源中的新檔案和目錄將複製到鏡像。同時建立第二個(暫存)文件,列出來源目錄中的目前文件和目錄;.currentfiles
  • 隨後,.recentfiles(列出先前備份的情況)與 進行比較.currentfiles僅有的.recentfiles不在其中的檔案.currentfiles顯然會從來源中刪除,並且將從目標中刪除。
  • 您手動新增至目標資料夾的檔案無論如何都不會被腳本“看到”,並且會被單獨保留。
  • 最後,臨時檔案.currentfiles被重新命名為.recentfiles下一個備份週期服務,依此類推。

劇本

#!/usr/bin/env python3
import os
import sys
import shutil

dr1 = sys.argv[1]; dr2 = sys.argv[2]

# --- choose verbose (or not)
verbose = True
# ---

recentfiles = os.path.join(dr2, ".recentfiles")
currentfiles = os.path.join(dr2, ".currentfiles")

if verbose:
    print("Counting items in source...")
    file_count = sum([len(files)+len(d) for r, d, files in os.walk(dr1)])
    print(file_count, "items in source")
    print("Reading directory & file structure...")
    done = 0; chunk = int(file_count/5); full = chunk*5

def show_percentage(done):
    if done % chunk == 0:
        print(str(int(done/full*100))+"%...", end = " ")

for root, dirs, files in os.walk(dr1):
    for dr in dirs:
        if verbose:
            if done == 0:
                print("Updating mirror...")
            done = done + 1
            show_percentage(done) 
        target = os.path.join(root, dr).replace(dr1, dr2)
        source = os.path.join(root, dr)
        open(currentfiles, "a+").write(target+"\n")
        if not os.path.exists(target):
            shutil.copytree(source, target)
    for f in files:
        if verbose:
            done = done + 1
            show_percentage(done)
        target = os.path.join(root, f).replace(dr1, dr2)
        source = os.path.join(root, f)
        open(currentfiles, "a+").write(target+"\n") 
        sourcedit = os.path.getmtime(source)
        try:
            if os.path.getmtime(source) > os.path.getmtime(target):
                shutil.copy(source, target)   
        except FileNotFoundError:
            shutil.copy(source, target)

if verbose:
    print("\nChecking for deleted files in source...")

if os.path.exists(recentfiles):
    recent = [f.strip() for f in open(recentfiles).readlines()]
    current = [f.strip() for f in open(currentfiles).readlines()]
    remove = set([f for f in recent if not f in current])
    for f in remove:
        try:
            os.remove(f)
        except IsADirectoryError:
            shutil.rmtree(f)
        except FileNotFoundError:     
            pass
        if verbose:
            print("Removed:", f.split("/")[-1])

if verbose:
    print("Done.")

shutil.move(currentfiles, recentfiles)

如何使用

  1. 將腳本複製到一個空文件中,另存為backup_special.py
  2. 如果需要,請更改腳本頭部的詳細選項:

    # --- choose verbose (or not)
    verbose = True
    # ---
    
  3. 使用來源和目標作為參數來運行它:

     python3 /path/to/backup_special.py <source_directory> <target_directory>
    

速度

我在網路磁碟機 (NAS) 上的 10 GB 目錄上測試了該腳本,其中包含約 40.000 個檔案和目錄,它與 rsync 幾乎同時進行了備份。

更新中整個目錄只比 rsync 多花了幾秒鐘,處理 40.000 個文件,這在我看來是可以接受的,並不奇怪,因為腳本需要將內容與上次製作的備份進行比較。

相關內容