有一种简洁的方法来测试bash中一组命令的退出状态吗?

时间:2012-10-19 19:02:20

标签: bash rsync exitstatus

我有一个简单的脚本从远程服务器提取数据,因为进程使用rsync生成数据:

while :
do
    rsync -avz --remove-source-files -e ssh me@remote:path/to/foo* ./

    rsync -avz --remove-source-files -e ssh me@remote:path/to/bar* ./

    rsync -avz --remove-source-files -e ssh me@remote:path/to/baz* ./

    rsync -avz --remove-source-files -e ssh me@remote:path/to/qux* ./

    sleep 900 #wait 15 minutes, try again
done

如果没有文件,rsync将返回退出状态12(显然)。如果上述rsync调用的 none 找到任何数据,我想从循环中断(生成数据的过程可能会退出)。为了缓解任何混淆,即使其中一个rsync进程成功,我也想要脱离循环。

在bash中有没有简洁的方法呢?

3 个答案:

答案 0 :(得分:2)

你可以通过累加返回值来做到这一点,这样如果它们都返回12,则总和为48:

while :
do
    rc=0
    rsync -avz --remove-source-files -e ssh me@remote:path/to/foo* ./
    let rc+=$?

    rsync -avz --remove-source-files -e ssh me@remote:path/to/bar* ./
    let rc+=$?

    rsync -avz --remove-source-files -e ssh me@remote:path/to/baz* ./
    let rc+=$?

    rsync -avz --remove-source-files -e ssh me@remote:path/to/qux* ./
    let rc+=$?

    if [[ $rc == 48 ]]; then  # 48 = 4 * 12
         break;
    fi

    sleep 900 #wait 15 minutes, try again
done

请注意,如果您获得另一个返回码总和为48的组合,即0 + 0 + 12 + 36

,这可能会受到影响

答案 1 :(得分:0)

这种方式计算由于没有文件而导致的失败次数。

while :
do
    nofile=0

    rsync -avz --remove-source-files -e ssh me@remote:path/to/foo* ./
    (( $? == 12 )) && let nofile++

    rsync -avz --remove-source-files -e ssh me@remote:path/to/bar* ./
    (( $? == 12 )) && let nofile++

    rsync -avz --remove-source-files -e ssh me@remote:path/to/baz* ./
    (( $? == 12 )) && let nofile++

    rsync -avz --remove-source-files -e ssh me@remote:path/to/qux* ./
    (( $? == 12 )) && let nofile++

    # if all failed due to "no files", break the loop
    if (( $nofile == 4 )); then break; fi

    sleep 900 #wait 15 minutes, try again
done

答案 2 :(得分:0)

受到其他答案的启发,我认为这是迄今为止我能做到的最干净的方式......

while :
do
    do_continue=0

    rsync -avz --remove-source-files -e ssh me@remote:path/to/foo* ./ && do_continue=1
    rsync -avz --remove-source-files -e ssh me@remote:path/to/bar* ./ && do_continue=1
    rsync -avz --remove-source-files -e ssh me@remote:path/to/baz* ./ && do_continue=1
    rsync -avz --remove-source-files -e ssh me@remote:path/to/qux* ./ && do_continue=1

    if [[ $do_continue == 0 ]]; then 
       break
    fi

    sleep 900 #wait 15 minutes, try again
done

可以进行更多重构以删除break语句和相关的条件测试:

do_continue=1
while [ do_continue -eq 1 ]; do
    do_continue=0
    rsync -avz --remove-source-files -e ssh me@remote:path/to/foo* ./ && do_continue=1
    #...
    sleep 900
done