我尝试过在 Python 中运行以及在命令行中运行。我已经仔细检查过:某些文件确实已从源中删除,但存在于link-dest
目标中。我尝试过多种选择。我尝试在路径末尾添加正斜杠,看看这是否会产生影响。所有情况下的路径都是简单的目录,永远不会以全局模式结束。我还查看了手册页。
顺便说一句,这应该不重要,但你永远不知道:我在 WSL(W10 操作系统)下运行它。
似乎没什么作用。
顺便说一下,源中删除的文件做在目标位置被删除(或者更确切地说不复制)(如果不是空运行)。
我想做的是找出link-dest
位置和源之间发生了哪些变化,以期在没有任何变化的情况下取消操作。但要做到这一点,我必须能够获取新文件或修改文件以及已删除文件的列表。
这是我一直在尝试的Python代码:
link_dest_setting = '' if most_recent_snapshot_of_any_type == None \
else f'--link-dest={most_recent_snapshot_of_any_type[0]}'
rsync_command_args = [ 'rsync',
'-v',
# '--progress',
# '--update',
'--recursive',
'--times',
'--delete',
# '--info=DEL',
'-n',
link_dest_setting, source_dir, new_snapshot_path, ]
print( f'running this: {rsync_command_args}')
result = subprocess.run( rsync_command_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
rsync_result_stdout = result.stdout.decode( 'utf-8' )
print( f'rsync_result stdout |{rsync_result_stdout}|')
rsync_result_stderr = result.stderr.decode( 'utf-8' )
print( f'rsync_result stderr |{rsync_result_stderr}|')
典型stdout
(试运行):
rsync_result stdout |sending incremental file list
./
MyModifiedFile.odt
sent 1,872 bytes received 25 bytes 3,794.00 bytes/sec
total size is 6,311,822 speedup is 3,327.27 (DRY RUN)
|
(没有报告错误stderr
)
刚刚找到了另一个选择,-i
.使用这个东西变得非常神秘:
rsync_result stdout |sending incremental file list
.d..t...... ./
>f.st...... MyModifiedFile.odt
sent 53,311 bytes received 133 bytes 35,629.33 bytes/sec
total size is 6,311,822 speedup is 118.10
|
编辑
典型的 BASH 命令:
rsync -virtn --delete --link-dest=/mnt/f/link_dest_dir /mnt/d/source_dir /mnt/f/destination_dir
原则上,试运行应该显示 link_dest_dir 下存在的文件/目录,但 source_dir 下不存在(已删除)的文件/目录。我无法让这个被显示。无论如何,我认为 Python 答案可能是一个更好的解决方案,因为扫描在第一次检测到差异时就会停止。
编辑2
(回答 roaima 的问题“你在保存什么?”)
我的“我的文档”目录有大约 6 GB 和数千个文件。如果没有发现差异,我的 Python 脚本需要 15 秒左右来扫描它(如果有差异则更短)。rsync
通常需要大约 2 分钟来完成复制(对绝大多数文件使用硬链接)。如果发现这是不必要的,因为源和位置之间没有变化link-dest
,那么我将不得不删除所有这些文件和硬链接。删除操作本身就时间而言非常昂贵。顺便说一句,这是一个外部高清旋转板类型。不是有史以来最慢的存储位置,但它有其局限性。
同样重要的是,因为rsync
至少根据我的发现,似乎无法报告源中已删除的文件,所以我怎么知道这个新快照与快照相同link-dest
?在这些快照位置中,我只想保留有限数量(例如 5 个)快照,但我只想在新快照与其前身不同时添加新快照。因此,尽管脚本可能每 10 分钟运行一次,但相邻快照之间的间隔可能是 40 分钟,甚至更长。
我看到你(roaima)有很高的声誉,并且似乎在rsync
.我想回答的简单问题是:是否可以rsync
在空运行时报告源中相对于 删除的文件/目录link-dest
?如果不是,这是一个错误/缺陷吗?因为手册页似乎确实声称(例如 with --info=DEL
)这应该发生。
答案1
你的问题的关键部分似乎是这些,
我只想在新快照与其前身不同时添加新快照。因此,虽然脚本可能每 10 分钟运行一次,但相邻快照之间的间隔可能是 40 分钟,或者更长
和
rsync 是否可以在空运行时报告源中相对于链接目标删除的文件或目录
我在这里的理解是,您已经实现了一个版本rsnapshot
,每次您考虑进行备份时,以前的备份目录成为您的--link-dest
目录。最大的区别是,如果当前源树和最近的备份之间没有更改,那么在您的情况下不需要进行备份。
在我的简短实验中,似乎可以简单地查看 的输出rsync
:如果有输出,则需要完成工作,如果没有,则没有工作。关键是直接查看链接目录
output=$(rsync -rti --delete --dry-run "$src/" "$lnk/" 2>&1 | grep -v '^[^*]d' | head -n1)
if [ -n "$output" ]
then
# Work to be done
rsync -rtiv --link-dest "$lnk/" "$src/" "$dst"
fi
目前我在测试中省略了目录,因此对目录的更改不会触发备份。如果您也关心目录的更改,请grep
从测试中删除过滤器
答案2
这是一种解决方法,因为它使用 Python。我一天中的大部分时间diff
都在尝试这两种方法。rsync
我根本无法rsync
报告已在源中删除并存在于该link-dest
位置(例如在试运行中)的文件/目录。diff
似乎确实可以完成这项工作,但对于大目录来说可能会非常冗长,并且您无法说“如果发现差异就停止”。这同样适用rsync
于此事。
import filecmp
def same_folders(dcmp):
if dcmp.diff_files or dcmp.left_only or dcmp.right_only:
return False
for sub_dcmp in dcmp.subdirs.values():
if not same_folders(sub_dcmp):
return False
return True
if same_folders(filecmp.dircmp( source_dir, link_dest_dir_path )):
print( 'NO CHANGE' )
# ... act accordingly
第一个实验似乎表明,这是一种查找两个目录之间差异的快速方法。顺便说一句,我还没有研究过使用哪种差异函数来生成dircmp.diff_files
(列出具有相同路径但不同的文件)。
left_only
和right_only
分别是在源中查找新文件/目录或已从源中删除的文件/目录。
这显然会在发现差异的那一刻停止。
我知道巴什很多小于Python...我想知道与上面等效的BASH是否可能?那么进行速度比较会很有趣......