29

I would like to create a loop that repeats a ncftp transfer if it returns an error.

I'm a little unsure how the exit code variable can be used in a loop. Would something like this work?

until [$? == 0]; do
    ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file
done
47

I found the basis for this elegant loop elsewhere on serverfault. Turns out there is no need save the exit code, as you can test directly on the command itself;

until ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file; do
  echo Tansfer disrupted, retrying in 10 seconds...
  sleep 10
done
| improve this answer | |
10

Almost. You are probably better saving the return value as a variable so that you can pre-set it before the loop. Otherwise it will be affected by the last-run command.

You might also want to sling a sleep in there to stop it respawning too quickly.

RET=1
until [ ${RET} -eq 0 ]; do
    ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file
    RET=$?
    sleep 10
done
| improve this answer | |
  • I think forgot to pass the exit code to the RET variable, but I get the idea. My main question is when will the until clause be evaluated? In C it won't be evaluated until after the first run of the loop, in which case my loop should work. Yours is still better, though, as it allows for intermediate commands such as the sleep. Thanks! – Roy Nov 3 '09 at 9:33
  • Well spotted. I've edited it. The clause will be evaluated before the first run. So previously it would use the return code of any preceding command. The double-equals aren't enforced by Bash but it makes good practice to use. – Dan Carley Nov 3 '09 at 9:51
  • == is for string equality not numeric, although I don't think it matters in this case... – Kyle Brandt Nov 3 '09 at 13:01
  • Single and double equals are the same. But it would be better to use integer equality now that you mention it. – Dan Carley Nov 3 '09 at 13:33
  • 1
    You don't need to test the return code number -- you can just test the return code of the program itself -- until program ; do sleep 3 ; done . – chris Nov 3 '09 at 22:15
5

Bit hacky but my solution was to just create a bash function which runs itself if it exits with a failure

function retry { the_command_you_want && echo "success" || (echo "fail" && retry) }; retry
| improve this answer | |
0

You can do a loop while your command returns error:

    while [ -n $(ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file) ]; do
            sleep 1;
    done;
| improve this answer | |
  • 3
    This answer needs explanation. – kasperd Dec 9 '16 at 21:51
  • @kasperd explanation added – Andrés Rivas Dec 12 '16 at 15:59
0

I've had a similar problem with needing to repeat curl requests, and the scripting was getting out of hand. As a result I created the retry tool:

retry ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file

In this case, the ncftpput command will be retried indefinitely until it returns a success status code, backing off by default for ten seconds in between.

Retry is available here: https://github.com/minfrin/retry

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.