jkr*_*ski 11 sync command-line backup rsync directory
我开始rsync使用它并尝试使用它来保持本地系统上的两个文件夹同步。我有一个源文件夹,其内容会随着时间的推移而发生变化(一些文件被添加,一些更改和一些删除)和一个我想几乎成为源镜像的目标文件夹。所以我尝试过像这样使用 rsync:
rsync -a --delete "${source_dir}" "${target_dir}";
这确实使目标的内容与源的内容完全相同。但是,我希望能够将一些文件添加到目标而不是源,但我不希望每次执行 rsync 时都将它们删除。另一方面,以前同步然后在源中被删除的文件仍然应该被删除。
有没有办法做到这一点,而不必为我想要排除的每个文件更改命令?
更新:我应该提到我不仅限于 rsync。如果另一个程序完成了工作,那也很好。我只是尝试使用 rsync 来解决这个问题。
rsync有一个名为--exclude-fromoption 的选项,它允许您创建一个文件,其中包含要排除的任何文件的列表。您可以在想要添加新排除项或删除旧排除项时更新此文件。
如果您在/home/user/rsync_exclude新命令中创建排除文件将是:
rsync -a --delete --exclude-from="/home/user/rsync_exclude" "${source_dir}" "${target_dir}"
Run Code Online (Sandbox Code Playgroud)
创建排除列表文件时,您应该将每个排除规则放在单独的行上。排除项与您的源目录相关。如果您的/home/user/rsync_exclude文件包含以下选项:
secret_file
first_dir/subdir/*
second_dir/common_name.*
Run Code Online (Sandbox Code Playgroud)
secret_file将排除在源目录中调用的任何文件或目录。${source_dir}/first_dir/subdir将被排除,但subdir将同步一个空版本。${source_dir}/second_dir带有前缀的文件都common_name.将被忽略。所以common_name.txt,common_name.jpg等等。既然你提到:我不仅限于rsync:
下面的脚本完全符合您的描述。
该脚本可以在详细模式下运行(在脚本中设置),这将输出备份(镜像)的进度。不用说,这也可以用于记录备份:
详细选项
.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)
Run Code Online (Sandbox Code Playgroud)
backup_special.py更改 - 如果需要 - 脚本头部的详细选项:
# --- choose verbose (or not)
verbose = True
# ---
Run Code Online (Sandbox Code Playgroud)使用源和目标作为参数运行它:
python3 /path/to/backup_special.py <source_directory> <target_directory>
Run Code Online (Sandbox Code Playgroud)我在一个 10 GB 的目录上测试了脚本,在我的网络驱动器 (NAS) 上有大约 40.000 个文件和目录,它与 rsync 几乎同时进行了备份。
在 40.000 个文件上更新整个目录只比 rsync 多花几秒钟,这是可以接受的,这并不奇怪,因为脚本需要将内容与上次备份的内容进行比较。
| 归档时间: |
|
| 查看次数: |
2108 次 |
| 最近记录: |