获取 rsync 来报告是否更新了任何本地文件

获取 rsync 来报告是否更新了任何本地文件

我正在运行 rsync 以从远程主机拉取到本地主机。

rsync -a --update user@remotehost:/files/ ~/files/

我正在从 java 运行该命令并使用退出代码来确定它是否成功。

如果有任何本地文件被修改,是否可以让该命令报告回来?通过退出代码进行报告是理想的选择。

答案1

您无法rsync通过退出代码告诉您这一点。退出代码已记录预定义含义。

我认为从 java 执行此操作的最佳方法是添加--info=NAME仅提及更新的目录和文件名的选项:

rsync -a --info=NAME --update user@remotehost/files/ ~/files/

这会在标准输出 (fd = 0) 上打印更新的文件和目录的名称,每行一个。

然后,您将收集输出rsync并计算字符串中换行符的数量。

我认为可以在这个答案中找到收集输出的好方法java,但我还没有尝试过:https://stackoverflow.com/a/9048519/5484716

不是使用redirectErrorStream或以任何其他方式合并标准输出和标准错误流。如果这样做,您将把错误消息算作更新的文件,而不是您想要的。

答案2

基于 @DavidKing 让 rsync 打印复制的文件名的想法,并使用 @yashma 的信息进行扩展,即当 stdin 为空时 grep 将退出非零退出状态,我们可以想出这个令人满意的简短而神秘的单行:

# prints file list, exits nonzero when that list is empty
rsync -a --info=NAME --update user@remotehost:/files/ ~/files/ | grep .

答案3

标志--infoonrsync将输出传输的任何文件的路径。的退出代码rsync指示成功/失败,因此如果不将脚本包装在命令周围,您将无法使用它,例如

#!/bin/bash

files=$(rsync -a --info=NAME --update user@remotehost/files/ ~/files/)

if [ $files = "" ]; then
  # files weren't transferred
  exit 0
else
  # files were transferred
  exit 1
fi

然后从 java 调用该脚本而不是rsync直接调用命令。 rsync可能会在传输的开头和结尾输出一些其他文本行,因此您可能需要调整语句if以考虑额外的输出行,但基本想法是可行的。

答案4

通过返回码获取信息的方法是编写一个 shell 脚本,rsync从 java 调用并执行 shell 脚本。正如我在下面概述的那样,这存在一些主要问题。 shell 脚本可能如下所示:

#!/bin/sh
if OUTPUT=$(rsync -a --info=NAME --update user@remotehost/files/ ~/files/)
then
    if [ "$OUTPUT" != "" ]                   # got output?
    then
        exit 0  # yes, success, "some" files were updated
    fi
fi
exit 1  # either rsync failed or no files were updated

这样做的主要问题是您将无法判断同步过程本身是否成功完成。您只知道文件是否已更新。这就是为什么我建议在 java 中收集输出并计算行数检查返回码在java中

相关内容