我想运行一个 rsync 作业,将数据从 A 复制到 B。处理后,目标上的数据将被删除。但是,处理后的数据不应再被复制。有没有办法让 rsync 记住目标上已删除的数据,而只复制源中的新数据?也许有办法制作一个持续的列表并从列表中排除数据?
答案1
有两种不同的方法可以实现:
选择需要传输的文件并将该列表提供给 rsync,这样只会复制这些文件。此
find
命令对此特别有用。
例如使用find -ctime 1 -print0 /path/ | rsync --files-from -
但其他来源、文件名模式、数据库查询、创建文件的应用程序的输入等也是选择要复制的特定文件的良好候选者。rsync 可以维护其执行操作的日志。(检查
man rsync
并查找--log-file=FILE
和--log-file-format=FMT
选项)。批处理成功后,将该日志中的文件/路径名附加到先前复制的文件列表中。然后在下一次--exclude-from=FILE
rsync 运行中使用该连接列表作为,以防止再次复制这些文件。
请注意,这两种方法都不是 100% 万无一失的,您需要仔细考虑边缘情况的影响、未复制的文件、第二次复制的文件以及状态/历史记录丢失时发生的情况。
答案2
我在寻找类似用例的解决方案时偶然发现了这个问题。
我写了一个脚本(我不是 Bash 专家,所以请谨慎使用),它可以解决两个目录的同步问题并保留历史记录。这是一种单向同步,源目录中的文件在第一次传输后永远不会同步到目标目录。
#!/bin/bash
#
# Sync two directories with rsync, but keep history to optimize the process.
# On subsequent runs it will only sync files added since last sync.
#
# Accepts two arguments source and destination directory.
# Make sure source and destination do not end with a slash.
# Script assumes that both source and destination directory already exist. It
# is meant only to sync source content to destination content.
#
# When started it will output where it saves history. Do not delete that file!
# Delete history file if you want to re-sync from clean state.
#
# Example usage
# In parent directory of Audiobooks run:
# ./sync_with_history.sh Audiobooks user@xhostname:/media/ServerMedia/Audiobooks
# to sync files to a remote server. You'll need ssh access set up.
#
# To sync local directories simply run:
# ./sync_with_history.sh Audiobooks /path/to/destination/Audiobooks
# in the parent directory of Audiobooks.
# Create history file name
escaped1=$(echo $1 | tr / -)
escaped2=$(echo $2 | tr / -)
sync_with_history_done_list="sync_with_history_done_list-$escaped1-to-$escaped2"
echo "Saving history to $sync_with_history_done_list"
# Ensure sync_with_history_done_list exists
touch $sync_with_history_done_list
# List all not rsync-ed files to a list
find $1 -mindepth 1 -type f -printf '%P\n' | grep -vFf $sync_with_history_done_list > sync_with_history_todo_list
cat sync_with_history_todo_list | while read line
do
echo "Sending: $line"
echo "$line" > files-to-include
# NOTE: use rsync -a if you want to keep permissions, owner, group etc.
# I use -r because I don't need those.
rsync -r --files-from=files-to-include $1/ $2/
echo "$line" >> $sync_with_history_done_list
done
# Clean up. leave only sync_with_history_done_list
touch files-to-include
rm files-to-include
rm sync_with_history_todo_list
你可以在 Github 上找到该脚本:https://gist.github.com/Spoygg/f6cdfbe6627a41fcf75fa7320b9dee3d 我在这里遗漏了更多细节。