我正在运行 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
标志--info
onrsync
将输出传输的任何文件的路径。的退出代码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中。