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
up vote 31 down vote accepted

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

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
  • 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

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

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;

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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