चूंकि आपने उल्लेख किया है: मैं rsync तक सीमित नहीं हूं:
दर्पण को बनाए रखने के लिए स्क्रिप्ट, लक्ष्य के लिए अतिरिक्त फ़ाइलों को जोड़ने की अनुमति
एक स्क्रिप्ट के नीचे जो आप वर्णन करते हैं वही करता है।
स्क्रिप्ट को वर्बोज़ मोड (स्क्रिप्ट में सेट होने के लिए) में चलाया जा सकता है , जो बैकअप (मिररिंग) की प्रगति को आउटपुट करेगा। यह कहने की आवश्यकता नहीं है कि इसका उपयोग बैकअप लॉग इन करने के लिए भी किया जा सकता है:
क्रिया विकल्प
संकल्पना
1. पहले बैकअप पर, स्क्रिप्ट:
- एक फ़ाइल (लक्ष्य निर्देशिका में) बनाता है, जहां सभी फाइलें और निर्देशिकाएं सूचीबद्ध हैं;
.recentfiles
- लक्ष्य निर्देशिका में सभी फ़ाइलों और निर्देशिकाओं की एक सटीक प्रतिलिपि (दर्पण) बनाता है
2. बैकअप पर अगले और इतने पर
- स्क्रिप्ट फाइलों की निर्देशिका संरचना और संशोधन की तारीख की तुलना करती है। स्रोत में नई फाइलें और डायरियां दर्पण में कॉपी की जाती हैं। एक ही समय में एक दूसरी (अस्थायी) फ़ाइल बनाई जाती है, वर्तमान फ़ाइलों को सूचीबद्ध करती है और स्रोत निर्देशिका में dirs;
.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)
कैसे इस्तेमाल करे
- स्क्रिप्ट को एक खाली फ़ाइल में कॉपी करें, इसे इस रूप में सहेजें
backup_special.py
परिवर्तन -आप चाहते हैं- स्क्रिप्ट के सिर में क्रिया विकल्प:
# --- choose verbose (or not)
verbose = True
# ---
तर्क के रूप में इसे स्रोत और लक्ष्य के साथ चलाएं:
python3 /path/to/backup_special.py <source_directory> <target_directory>
गति
मैंने अपने नेटवर्क ड्राइव (NAS) पर कुछ 40.000 फाइलों और डायरियों के साथ 10 जीबी निर्देशिका पर स्क्रिप्ट का परीक्षण किया, इसने बैकअप को rsync के समान समय में बनाया।
पूरी निर्देशिका को अपडेट करने में rsync की तुलना में केवल कुछ सेकंड अधिक, 40.000 फाइलों पर लिया गया, जो कि इमो स्वीकार्य है और कोई आश्चर्य की बात नहीं है, क्योंकि स्क्रिप्ट को अंतिम बने बैकअप के लिए सामग्री की तुलना करने की आवश्यकता है।