我有一个在两台服务器上发生更改的文件系统,也需要复制到 Amazon S3。
直到最近,使用 Unison 在两个服务器之间同步文件系统,然后使用 s3sync.rb 复制到 S3 一直是一个很好的解决方案。
现在文件系统已接近 50GB,s3sync.rb 已成为瓶颈,因为它需要检查每个文件的新鲜度(我们使用 --no-md5 标志)。
所以我现在有一个需要文件列表的脚本,它会使用 s3cmd.rb 更新这些文件,并且只更新这些文件
我原本希望可以使用 unison.log 文件来获取要传递的文件的规范列表,但其格式根据对文件发生的操作而有所不同(新文件、从本地替代文件复制、重命名等)。
unison 是否能够生成除 unison.log 中留下的文件之外的已更改文件的日志或列表?
目前,这是我从 unison.log 中提取文件列表的方式(我故意忽略了删除)
# Ignore deletes and get the list of new & changed files
grep -v '\[END\] Deleting ' /tmp/unison.log | grep '\[END\]' $unisonlog | sed -re 's/\[END\] (Copying|Updating file) //' > /tmp/changed-files.log
# Files that unison lists as shortcuts are harder as it doesn't always prefix them with their full path
# so before adding them to the log, find the files in the relevant directory
grep 'Shortcut: copying ' /tmp/unison.log | sed -re 's/Shortcut: copying (.*)+ from local file.*/\1/' | while read file
do
echo "Having to look for $file in source directory"
find /ebs/src -wholename "*$file" >> /tmp/changed-files.log
done
答案1
一个想法是使用stdout
Unison 在运行时生成的。Unison 在stdout
“寻找变化”时会使用一些垃圾来在终端中创建动态效果。通过删除包含回车符 (CR) 的每一行,可以相当轻松地删除这些垃圾(在 vim 中,这类似于按+然后+输入的:%s/^.*^M.*$\n//g
内容)。结果看起来像^M
CrtlVCrtlM
<---- new dir bar/foo/newdir
deleted ----> bar/user/oldfile1
deleted ----> bar/user/oldfile2
<---- new file foobar/test/quiz.txt
<---- changed foobar/test/quiz.txt
这比 Unison 的默认日志更容易解析。
不过,更好的想法可能是完全忘记解析Unison的输出,而是使用inotifywait
。您可以设置inotifywait
监视某个目录并报告任何更改、移动、创建等的文件。
inotifywait --event modify,attrib,move,create,delete \
--daemon \
--outfile /path/to/output.log \
--recursive \
--quiet \
--format %w%f \
'/watch/directory/'
inotifywait
这将作为守护进程运行,并生成一个非常好的、不断更新的列表 ( output.log
),其中包含发生指定事件之一的所有文件的绝对路径/watch/directory/
。您可能需要更改给定的事件和/或利用选项--exclude
来获取确切地您想要与 S3 同步的文件列表。