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

问题描述:

我有一个简单的脚本来从远程服务器获取数据的过程中它使用rsync产生:有没有一种简单的方法来测试bash中一组命令的退出状态?

while : 
do 
    rsync -avz --remove-source-files -e ssh [email protected]:path/to/foo* ./ 

    rsync -avz --remove-source-files -e ssh [email protected]:path/to/bar* ./ 

    rsync -avz --remove-source-files -e ssh [email protected]:path/to/baz* ./ 

    rsync -avz --remove-source-files -e ssh [email protected]:path/to/qux* ./ 

    sleep 900 #wait 15 minutes, try again 
done 

如果没有文件,rsync返回退出状态12(显然)。如果上面的调用rsync找到任何数据,我想打破循环(生成数据的过程可能已退出)。为了减轻任何困惑,我做了而不是想要从循环中突破,如果即使是1的rsync进程成功。

在bash中有一个简洁的方法吗?

+0

退出状态12似乎与协议数据流中的错误有关。你想退出任何*非零退出状态(来自所有'rsync'进程)的循环吗? – ezod

+0

@ezod - 我认为任何非零退出状态都足够让我打破(但只有当它们都不为零时)。 – mgilson

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

while : 
do 
    nofile=0 

    rsync -avz --remove-source-files -e ssh [email protected]:path/to/foo* ./ 
    (($? == 12)) && let nofile++ 

    rsync -avz --remove-source-files -e ssh [email protected]:path/to/bar* ./ 
    (($? == 12)) && let nofile++ 

    rsync -avz --remove-source-files -e ssh [email protected]:path/to/baz* ./ 
    (($? == 12)) && let nofile++ 

    rsync -avz --remove-source-files -e ssh [email protected]: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 

您可以通过添加了返回值,所以,如果他们都返回12,总和是48做到这一点:

while : 
do 
    rc=0 
    rsync -avz --remove-source-files -e ssh [email protected]:path/to/foo* ./ 
    let rc+=$? 

    rsync -avz --remove-source-files -e ssh [email protected]:path/to/bar* ./ 
    let rc+=$? 

    rsync -avz --remove-source-files -e ssh [email protected]:path/to/baz* ./ 
    let rc+=$? 

    rsync -avz --remove-source-files -e ssh [email protected]: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

+0

我想过这样的事情。我不想依靠它实际上使用退出状态12,虽然...这是更多布尔类型的事情。我想我可以做一些像rsync ... ||让rc + = 1'然后'if [[$ rc -eq 4]];然后打破; fi' ... – mgilson

+0

好主意,但为了避免担心其他组合,为什么不把它们相互追加$ rc值,然后在* [1-9] *中使用'case $ rc *)print“found non -zero退出代码= $ rc,无法继续“; 1号出口;; esac'。祝你们好运。 – shellter

+0

只需将它们相加并打破总和不为零的情况。 – chepner

由其他答案的启发,我觉得这是我能做到这一点迄今最清晰的方式...

while : 
do 
    do_continue=0 

    rsync -avz --remove-source-files -e ssh [email protected]:path/to/foo* ./ && do_continue=1 
    rsync -avz --remove-source-files -e ssh [email protected]:path/to/bar* ./ && do_continue=1 
    rsync -avz --remove-source-files -e ssh [email protected]:path/to/baz* ./ && do_continue=1 
    rsync -avz --remove-source-files -e ssh [email protected]: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 [email protected]:path/to/foo* ./ && do_continue=1 
    #... 
    sleep 900 
done