문제

I have a simple script to pull data from a remote server as a process generates it using 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

If there are no files, rsync returns exit status 12 (apparently). In the event that none of the above calls to rsync finds any data, I would like to break from the loop (the process generating the data probably exited). To alleviate any confusion, I do not want to break from the loop if even 1 of the rsync processes succeed.

Is there a succinct way to do that in bash?

도움이 되었습니까?

해결책

This way counts the number of fails due to no file.

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

다른 팁

You could do it by adding up the return values, so that if they all return 12, the sum is 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

Note that this may suffer if you get another combination of return codes sums to 48, i.e. 0 + 0 + 12 + 36

Inspired by the other answers, I think this is the cleanest way I can do it so far ...

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

which could be refactored more to remove the break statement and associated conditional test:

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top