당신이 언급 한 이후 : 나는 rsync로 제한되지 않습니다.
대상에 추가 파일을 추가 할 수 있도록 미러를 유지하는 스크립트
정확하게 설명하는 스크립트 아래.
스크립트는 상세 모드 (스크립트에서 설정) 로 실행할 수 있으며 , 백업 진행률 (미러링)을 출력합니다. 백업을 기록하는 데 사용할 수도 있습니다.
상세 옵션
개념
1. 첫 번째 백업에서 스크립트는 다음과 같습니다.
- 모든 파일과 디렉토리가 나열되는 파일을 대상 디렉토리에 작성합니다.
.recentfiles
- 대상 디렉토리에있는 모든 파일 및 디렉토리의 정확한 사본 (미러)을 작성합니다.
다음에 백업 등
- 스크립트는 파일의 디렉토리 구조와 수정 날짜를 비교합니다. 소스의 새 파일과 디렉토리가 미러에 복사됩니다. 동시에 두 번째 (임시) 파일이 작성되어 소스 디렉토리에 현재 파일과 디렉토리가 나열됩니다.
.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
스크립트 헤드에서 verbose 옵션을 원하는 경우 변경하십시오.
# --- choose verbose (or not)
verbose = True
# ---
source 및 target을 인수로 사용하여 실행하십시오.
python3 /path/to/backup_special.py <source_directory> <target_directory>
속도
내 네트워크 드라이브 (NAS)에 약 40.000 개의 파일과 디렉토리가있는 10GB 디렉토리에서 스크립트를 테스트하여 rsync와 거의 같은 시간에 백업을 만들었습니다.
전체 디렉토리를 업데이트 하는 데는 40.000 파일에서 rsync보다 몇 초 밖에 걸리지 않았습니다. 스크립트는 내용을 마지막으로 백업 한 내용과 비교해야하기 때문에 당연한 일입니다.