我的美元?命令成功代码失败,原因



在我的bash脚本中,如果rsync在放弃之前失去了与目标的连接,我会尝试让它重试10次。

我知道这段代码会捕获所有错误,但我现在可以接受。

我的代码是:

lops="0"
while true; do
    let "lops++"
    rsync $OPT $SRCLINUX $TRG 2>&1 | tee --append ${LOGFILE}
    if [ "$?" -eq "0" ]; then
        echolog "rsync finished WITHOUT error after $lops times"
        break 
    else
        echolog "Re-starting rsync for the ${lops}th time due to ERRORS"
    fi
    if [[ "$lops" == "10" ]]; then
        echolog "GAVE UP DUE TO TOO MANY rsync ERRORS - BACKUP NOT FINISHED"
        break 
    fi
done

它没有按预期工作,以下是第一个错误发生的情况:

TDBG6/
rsync: connection unexpectedly closed (131505 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(226) [sender=3.1.1]
rsync finished WITHOUT error after 1 times

这是因为$吗?包含tee的返回值,而不是rsync

我该怎么解决这个问题?(我个人受Linux语法限制:)

我认为至少有两种可能性可以解决您的问题:

  1. 使用PIPESTATUS:

    一个数组变量,包含最近执行的前台管道(可能只包含一个命令)中进程的退出状态值列表。

    用作:

    rsync $OPT $SRCLINUX $TRG 2>&1 | tee --append ${LOGFILE}
    if (( PIPESTATUS[0] == 0 )); then
    
  2. 使用rsync--log-file选项。

注:

  • 您的代码中缺少许多引号
  • 不要使用大写的变量名
  • 不要使用let,而使用((...))进行算术运算

除了处理混淆退出代码的管道的其他建议外,您还可以通过使用流程替换来避免管道,如下所示:

rsync "$OPT" "$SRCLINUX" "$TRG" &> >( tee --append "${LOGFILE}" )

它将把stdoutstderr(即&>部分)重定向到一个"文件"中,该文件连接到>(...)中进程的stdin,在这种情况下是您想要的tee命令。所以它很像管道,但没有管道(管道在幕后连接左边的stdout和右边的stdin,我们只是在这里公开了它)。

我认为状态是管道中最后一个命令的状态。

我不知道如何处理这个问题,但对于这个特定的情况,你可以重定向整个循环的输出:

while true; do
    ...
done | tee -a "$LOGFILE"

根据它的用途,这也可能意味着你不需要"回声日志"功能。

最新更新