Bahsettiğinizden beri: rsync ile sınırlı değilim:
Yansımayı korumak için komut dosyası, hedefe fazladan dosya eklenmesine izin verme
Tam olarak tarif ettiğiniz şeyi yapan bir komut dosyasının altında.
Komut dosyası , yedeklemenin ilerlemesini (yansıtma) çıkaracak ayrıntılı modda (komut dosyasında ayarlanacak) çalıştırılabilir. Bunun yedeklemeleri günlüğe kaydetmek için de kullanılabileceğini söylemeye gerek yok:
Ayrıntılı seçenek
Kavram
1. İlk yedeklemede komut dosyası:
- tüm dosyaların ve dizinlerin listelendiği bir dosya (hedef dizinde) oluşturur;
.recentfiles
- hedef dizindeki tüm dosyaların ve dizinlerin tam bir kopyasını (ayna) oluşturur
2. sonraki ve böylece yedekleme
- Komut dosyası, dosyaların dizin yapısını ve değişiklik tarihlerini karşılaştırır. Kaynaktaki yeni dosyalar ve dizinler aynaya kopyalanır. Aynı zamanda, kaynak dizindeki geçerli dosyaları ve dizinleri listeleyen ikinci (geçici) bir dosya oluşturulur;
.currentfiles
.
- Daha sonra,
.recentfiles
(önceki yedeklemedeki durumu listelemek) ile karşılaştırılır .currentfiles
. Yalnızca içinde.recentfiles
bulunmayan dosyalar .currentfiles
kaynaktan açıkça kaldırılır ve hedeften kaldırılır.
- Hedef klasöre el ile eklediğiniz dosyalar komut dosyası tarafından "görülmez" ve tek başına bırakılır.
- Son olarak, geçici
.currentfiles
olarak bir .recentfiles
sonraki yedekleme döngüsüne hizmet edecek şekilde yeniden adlandırılır .
Senaryo
#!/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)
Nasıl kullanılır
- Komut dosyasını boş bir dosyaya kopyalayın,
backup_special.py
Komut dosyasının başındaki ayrıntılı seçeneği (isterseniz) değiştirin:
# --- choose verbose (or not)
verbose = True
# ---
Kaynağı ve hedefi bağımsız değişken olarak çalıştırın:
python3 /path/to/backup_special.py <source_directory> <target_directory>
hız
Komut dosyasını 10 GB'lık bir dizinde ağ sürücümde (NAS) 40.000 dosya ve dizinle test ettim, yedeklemeyi hemen hemen rsync ile aynı zamanda yaptım.
Tüm dizini güncellemek , 40.000 dosyada rsync'den sadece birkaç saniye daha sürdü, bu imo kabul edilebilir ve sürpriz değil, çünkü komut dosyasının içeriği son yapılan yedekle karşılaştırması gerekiyor.