我经常rsnapshot
将系统的文件系统备份到远程服务器。
(对于那些熟悉rsync
但不太习惯的人rsnapshot
来说,这里是对其工作原理的简要介绍。备份是源文件系统树的逐个文件副本,很像cp -a
会产生的结果。“当前”备份始终是hourly.0
,并且前一个是hourly.1
。每次备份开始时,这些名称都会轮换,rsnapshot
用于rsync --link-dest
将未更改的文件硬链接到hourly.0
前一个备份树中的相应条目。hourly.1
)
如果备份失败,则将先前的备份复制(链接)cp -al
到当前备份,以便始终显示已进行备份。
我想要的是,如果自上次备份以来没有发生任何更改,请避免进行备份。这可能包括备份失败,或者只是源文件系统自上次备份以来没有被修改。 (如果您愿意,“进行备份”可以改写为“删除不必要的备份”。)
我考虑过在hourly.0
树中查找其他地方未硬链接的文件,如果没有,则只需删除备份树即可。这不会处理在其备份中其他位置有效链接的文件,并且也无法考虑对目录的更改。我还考虑过使用rsync --dry-run
比较两个备份树并查看其输出,但这感觉有点难看。
有更好的解决方案吗?
答案1
快照之后,您可以使用rsnapshot diff
which 调用rsnapshot-diff
来记录两个快照之间的差异。它只是比较 inode 编号,因此相当有效。
或者,在每次备份之前在备份树外部创建一个文件来记录时间,touch timestamp
.然后在新的备份之前,创建一个新的时间戳,touch timestamp.new
并测试是否有任何文件或目录的时间比旧时间戳更新
find tree -newer timestamp
如果没有,请不要进行备份。无论如何,mv timestamp.new timestamp
下次吧。这假设您没有操作文件和目录时间戳的应用程序。
答案2
我也认为这是一种可能性,它比优秀的更通用提案我已接受来自嗯。
listfiles()
{
(
# List attributes of file tree, discarding inode number
cd "$1" 2>/dev/null && find . -type f -ls | sed -r 's/^ *[1-9][0-9]*//' | sort
)
}
listfiles hourly.1 >/tmp/list1
listfiles hourly.0 >/tmp/list0
cmp -s /tmp/list1 /tmp/list0 && echo "the same" || echo "different"
这也会忽略与文件关联但未通过 .txt 列出的 ACL 和扩展属性find -ls
。然而,就我的目的而言,这是可以接受的。