Karena Anda menyebutkan: Saya tidak terbatas pada rsync:
Script untuk mempertahankan mirror, memungkinkan untuk menambahkan file tambahan ke target
Di bawah ini skrip yang melakukan apa yang Anda gambarkan
Skrip dapat dijalankan dalam mode verbose (diatur dalam skrip), yang akan menampilkan progres cadangan (mirroring). Tidak perlu mengatakan ini juga dapat digunakan untuk mencatat cadangan:
Opsi verbose
Konsep
1. Pada cadangan pertama, skrip:
- membuat file (dalam direktori target), di mana semua file dan direktori terdaftar;
.recentfiles
- membuat salinan persis (mirror) dari semua file dan direktori di direktori target
2. Pada cadangan berikutnya dan seterusnya
- Skrip membandingkan struktur direktori dan tanggal modifikasi file. File dan dirs baru di sumber disalin ke cermin. Pada saat yang sama file kedua (sementara) dibuat, daftar file saat ini dan direktori dalam direktori sumber;
.currentfiles
.
- Selanjutnya,
.recentfiles
(daftar situasi pada cadangan sebelumnya) dibandingkan dengan .currentfiles
. Hanya file .recentfiles
yang tidak ada di dalamnya yang .currentfiles
jelas dihapus dari sumbernya, dan akan dihapus dari target.
- File yang Anda tambahkan secara manual ke folder target tidak "dilihat" oleh skrip, dan dibiarkan sendiri.
- Akhirnya, sementara
.currentfiles
diganti namanya .recentfiles
untuk melayani siklus cadangan berikutnya dan seterusnya.
Naskah
#!/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)
Cara Penggunaan
- Salin skrip ke file kosong, simpan sebagai
backup_special.py
Ubah -jika Anda mau- opsi verbose di bagian atas skrip:
# --- choose verbose (or not)
verbose = True
# ---
Jalankan dengan sumber dan target sebagai argumen:
python3 /path/to/backup_special.py <source_directory> <target_directory>
Kecepatan
Saya menguji script pada direktori 10 GB dengan sekitar 40.000 file dan direktori pada drive jaringan saya (NAS), itu membuat cadangan dalam waktu yang hampir bersamaan dengan rsync.
Memperbarui seluruh direktori hanya membutuhkan beberapa detik lebih dari rsync, pada 40.000 file, yang dapat diterima dan tidak mengejutkan, karena skrip perlu membandingkan konten dengan cadangan yang terakhir dibuat.