我有一个脚本,它使用 rsync 在远程 -> 本地场景中同步数据。运行 rsync 命令后,立即检查错误代码是否为零。如果其为零,则执行进一步的命令。然而,这没有考虑到 rsync 可能已成功运行但实际上并未进行任何更改的事实。因此,无论如何,等零条件都会运行,这有点多余。
rsync -aEivm --delete /path/to/remote/ /path/to/local/
if [ $? -eq 0 ]; then
# Success do some more work!
else
# Something went wrong!
exit 1;
fi
扩展此方法以检查是否确实存在基于运行的 rsync 命令的任何更改的最佳方法是什么。我读过 -i 标志可以向标准输出提供输出,但是如何将其放置在条件块中?
答案1
根据对我原来问题的评论,使用 -i 标志将 rsync 输出到 stdout,并使用非字符串检查条件来查看错误代码检查中是否有任何实际更改。将 rsync 命令包装在变量中可以完成检查。
RSYNC_COMMAND=$(rsync -aEim --delete /path/to/remote/ /path/to/local/)
if [ $? -eq 0 ]; then
# Success do some more work!
if [ -n "${RSYNC_COMMAND}" ]; then
# Stuff to run, because rsync has changes
else
# No changes were made by rsync
fi
else
# Something went wrong!
exit 1
fi
潜在的缺点是,您必须丢失详细的输出,但您始终可以将其记录到文件中。
答案2
我想要一个更严格的解决方案。我不想 grep for Number of created files:
(消息可能是另一种语言)或删除-v
输出中除两行之外的所有行(谁知道rsync
下一个版本中将打印什么摘要?)。
编辑:我发现你可以将 a 的rsync
输出格式设置为列出已更改的文件--out-format
:
rsync -a --verbose source-dir target-dir \
--out-format='changed file: %i %n%L' \
| fgrep 'changed file:'
或者,如果您不关心文件时间但想要进行最少的复制,则可以使用扩展和清理的变体-a
:
rsync -r --links --devices --specials \
--delete --checksum \
--omit-dir-times --omit-link-times --ignore-times \
--prune-empty-dirs \
--verbose \
source-dir target-dir
旧答案:
我发现您可以设置 a 日志的格式rsync
,但不能设置其 stdout 的格式(请参阅man rsyncd.conf
)。
例如,添加“文件已更改!”到具有实际更改的文件的每一行,然后grep
对其进行:
rsync -a \
--log-file=/tmp/rsync.log \
--log-file-format="File changed! %f %i" \
source-dir target-dir
if fgrep "File changed!" /tmp/rsync.log > /dev/null; then
echo "rsync did something!"
fi