script bash: repita o comando se retornar um erro

23

Gostaria de criar um loop que repita uma transferência ncftp se retornar um erro.

Estou um pouco inseguro de como a variável de código de saída pode ser usada em um loop. Algo assim funcionaria?

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

Respostas:

40

Eu encontrei a base para esse loop elegante em outro lugar na falha do servidor. Acontece que não há necessidade de salvar o código de saída, pois você pode testar diretamente no próprio comando;

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

Quase. Provavelmente, você está melhor salvando o valor de retorno como uma variável para poder pré-configurá-lo antes do loop. Caso contrário, será afetado pelo comando de última execução.

Você também pode colocar um sleeppara impedir que ele reaparecer rapidamente.

RET=1
until [ ${RET} -eq 0 ]; do
    ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file
    RET=$?
    sleep 10
done
Dan Carley
fonte
Acho que esqueci de passar o código de saída para a variável RET, mas entendi a ideia. Minha principal pergunta é quando será avaliada a cláusula até? Em C, ele não será avaliado até depois da primeira execução do loop, caso em que meu loop funcionará. O seu ainda é melhor, pois permite comandos intermediários, como o sono. Obrigado!
214 Roy Roy
Bem manchado. Eu editei. A cláusula será avaliada antes da primeira execução. Portanto, anteriormente, ele usaria o código de retorno de qualquer comando anterior. O duplo-igual não é imposto pelo Bash, mas é uma boa prática de uso.
11119 Dan Carley #
== é para a igualdade de cadeia não numérico, embora eu não acho que importa neste caso ...
Kyle Brandt
Simples e duplo iguais são iguais. Mas seria melhor usar igualdade de número inteiro agora que você mencionou.
11119 Dan Carley #
1
Você não precisa testar o número do código de retorno - você pode apenas testar o código de retorno do próprio programa - até o programa; dorme 3; feito .
chris
3

Um pouco hacky, mas minha solução foi apenas criar uma função bash que é executada automaticamente se sair com falha

function retry { the_command_you_want && echo "success" || (echo "fail" && retry) }; retry
Qwertie
fonte
0

Você pode fazer um loop enquanto seu comando retorna erro:

    while [ -n $(ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file) ]; do
            sleep 1;
    done;
Andrés Rivas
fonte
3
Esta resposta precisa de explicação.
kasperd
@kasperd explicação adicionada
Andrés Rivas