如何从 rsync 输出已更改文件的列表?

如何从 rsync 输出已更改文件的列表?

我在 bash 脚本中使用 rsync 来保持几台服务器和一台 NAS 之间的文件同步。我遇到的一个问题是尝试生成 rsync 期间已更改的文件列表。

我的想法是,当我运行 rsync 时,我可以将已更改的文件输出到文本文件中 - 更希望在内存中有一个数组 - 然后在脚本存在之前我可以在仅有的已更改的文件。

有谁找到完成这项任务的方法吗?

# specify the source directory
source_directory=/Users/jason/Desktop/source

# specify the destination directory
# DO NOT ADD THE SAME DIRECTORY NAME AS RSYNC WILL CREATE IT FOR YOU
destination_directory=/Users/jason/Desktop/destination

# run the rsync command
rsync -avz $source_directory $destination_directory

# grab the changed items and save to an array or temp file?

# loop through and chown each changed file
for changed_item in "${changed_items[@]}"
do
        # chown the file owner and notify the user
        chown -R user:usergroup; echo '!! changed the user and group for:' $changed_item
done

答案1

您可以使用 rsync 的--itemize-changes( -i) 选项来生成如下所示的可解析输出:

~ $ rsync src/ dest/ -ai
.d..t.... ./
>f+++++++ newfile
>f..t.... oldfile

~ $ echo 'new stuff' > src/newfile

~ $ !rsync
rsync src/ dest/ -ai
>f.st.... newfile

第一个位置的字符>表示文件已更新,其余字符表示更新原因,例如这里s表示t文件大小和时间戳发生了变化。

获取文件列表的一种快速而肮脏的方法可能是:

rsync -ai src/ dest/ | egrep '^>'

显然更高级的解析可以产生更清晰的输出:-)

我在尝试找出--itemize-changes其引入时间时偶然发现了这个很棒的链接,非常有用:

http://andreafrancia.it/2010/03/understanding-the-output-of-rsync-itemize-changes.html(存档链接)

答案2

使用-n标志,结合-c校验和标志和-i标志:

# rsync -naic test/ test-clone/
>fcst...... a.txt
>fcst...... abcde.txt
>fcst...... b.txt

在此示例中,根据文件本身的内容(由校验和确定),三个文件已发生更改。但是,由于标志,没有进行文件-n同步

奖金

如果要在更改的文件上运行 chown,请使用sed或类似命令将其解析出来并使用 xargs 进行处理,例如:

rsync -naic test/ test-clone/ | sed 's/............//' | xargs -I+ sudo chown root "test-clone/+"

答案3

这个问题有点老了,但我认为值得补充:

-i--out-format='%i %n%L'

%i表示一个神秘的、11 个字符的输出,其格式为字符串YXcstpoguax;ref man rsync,。-itemize-changes并且%n表示文件名(log format的部分man rsyncd.conf);%L当有符号链接需要更新时发挥作用。

PS rsync 版本 3.1.0

答案4

总结一些其他的答案(特别是@Cychih的答案),你可以像这样获取已更改文件的列表:

rsync --out-format='%n' src/ dest/

这将打印仅有的已更改的文件,例如;

rsync --out-format='%n' src/ dest/
a.txt
bcde.txt
b.txt

您可以通过以下方式将其保存到列表中:

changed_items=($(rsync --out-format='%n' src/ dest/))
for item in "${items[@]}"; do
   echo $item
   echo $item
done

您可以将它们传送到另一个命令,如下所示:

rsync --out-format='%n' src/ dest/ | xargs open

请注意,包含-acz(存档、校验和以及压缩)标志也是很常见的。

相关内容