![仅在检测到更改时使用 rsync 创建文件版本?](https://linux22.com/image/211597/%E4%BB%85%E5%9C%A8%E6%A3%80%E6%B5%8B%E5%88%B0%E6%9B%B4%E6%94%B9%E6%97%B6%E4%BD%BF%E7%94%A8%20rsync%20%E5%88%9B%E5%BB%BA%E6%96%87%E4%BB%B6%E7%89%88%E6%9C%AC%EF%BC%9F.png)
我最近一直在尝试使用 rsync 作为系统上某些文件的版本控制/备份手段。
我的目标本质上是设置 rsync 来监视某些特定文件,并且如果/当这些文件更改为 rysnc 时,则将所述文件作为单独的文件复制到另一个目标(而不是覆盖初始备份文件) 。
所以目前,我所拥有的是:
rsync ~/Database/original.sqlite ~/Backup/backup`date +'.%F_%H-%M-%S'`.sqlite
我在 launchd 中以 1 分钟计时器作为代理运行它。因此,按照现在的情况,无论如何,rsync 基本上都会每分钟继续制作该文件的新副本。
如果我有一种方法让 rsync 检查备份文件夹中的最新版本,与数据库文件夹中的原始文件进行比较,那么如果文件不同,则创建一个新的备份版本,那就完美了。
我真的在扩展 rsync 的限制吗?
预先感谢您的任何建议。
答案1
如果它始终运行,对我来说最简单的解决方案就是检查文件是否在最后一刻被编辑过,如果是,则进行备份。
#!/bin/bash
# get current time
now="$(date +'%s')"
# get modification time of fime
modified="$(stat -c '%Y' ~/Database/original.sqlite)"
# check if modified in the last minute
if (( modified > (now - 60) )) ; then
rsync ~/Database/original.sqlite ~/Backup/backup`date +'.%F_%H-%M-%S'`.sqlite
fi
如果您希望它非常强大,您可以将上次备份的名称或其时间戳写入文件,然后进行检查。但是,不确定您是否想让它变得更简单。
我想另一种选择是让脚本本身负责每分钟触发一次,并在启动时在后台运行一次。然后脚本可以跟踪上次修改时间本身:
#!/bin/bash
# initialize last backup at 0
lastbackup=0
while true ; do
# get modification time
modified="$(stat -c '%Y' ~/Database/original.sqlite)"
# check to see if it's been changed
if (( modified > lastbackup )) ; then
# do backup
rsync ~/Database/original.sqlite ~/Backup/backup`date +'.%F_%H-%M-%S'`.sqlite
# set the variable to its current modification time
lastbackup="$modified"
fi
done
答案2
你或许可以使用:
rsync -au ~/Database/original.sqlite ~/Backup/
-u 选项意味着
--update, -u 跳过接收器上较新的文件
因此,rsync 仅当源文件夹中的文件较新时才会覆盖目标文件夹中的文件。
然后你可以监控变化目标文件夹中的特定文件,并在必要时进行复制。
- 更新 -
要监视文件的更改,您可以按照以下脚本的行执行某些操作(改编自链接的问题)。请注意,这需要inotify-tools
(sudo apt install inotify-tools
在 Ubuntu 中)
#! /bin/bash
f=~/Backup/original.sqlite
touch $f
inotifywait -m -e modify "$f" --format "%e" | while read -r event; do
if [ "$event" == "MODIFY" ]; then
prev="$curr"
curr=$(<"$f")
[ "$curr" == "$prev" ] || echo "$f changed: do something"
fi
done
如果运行该脚本,它将监视更改。该脚本仅echo "$f changed: do something"
作为示例,但您可以对其进行调整以执行您喜欢的任何操作。例如cp $f destination_file
。