script bash: ripeti il ​​comando se restituisce un errore


23

Vorrei creare un ciclo che ripete un trasferimento ncftp se restituisce un errore.

Non sono sicuro di come la variabile del codice di uscita possa essere utilizzata in un ciclo. Qualcosa del genere funzionerebbe?

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

Risposte:


40

Ho trovato le basi per questo elegante loop altrove su serverfault. Si scopre che non è necessario salvare il codice di uscita, poiché è possibile testare direttamente sul comando stesso;

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

8

Quasi. Probabilmente stai meglio salvando il valore restituito come variabile in modo da poterlo preimpostare prima del ciclo. Altrimenti sarà influenzato dal comando last-run.

Potresti anche voler mettere una fionda sleeplì dentro per impedirne la rigenerazione troppo in fretta.

RET=1
until [ ${RET} -eq 0 ]; do
    ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file
    RET=$?
    sleep 10
done

Penso di aver dimenticato di passare il codice di uscita alla variabile RET, ma ho avuto l'idea. La mia domanda principale è quando verrà valutata la clausola until? In C non verrà valutato fino a dopo la prima esecuzione del ciclo, nel qual caso il mio ciclo dovrebbe funzionare. Il tuo è comunque migliore, poiché consente comandi intermedi come il sonno. Grazie!
Roy,

Ben individuato. L'ho modificato. La clausola verrà valutata prima della prima esecuzione. Quindi in precedenza avrebbe usato il codice di ritorno di qualsiasi comando precedente. I doppi uguali non sono applicati da Bash ma sono buone pratiche da usare.
Dan Carley,

== è per l'uguaglianza delle stringhe non numerica, anche se non credo che in questo caso sia importante ...
Kyle Brandt,

Uguali singoli e doppi sono uguali. Ma sarebbe meglio usare l'uguaglianza dei numeri interi ora che lo dici.
Dan Carley,

1
Non è necessario testare il numero del codice di ritorno - si può semplicemente provare il codice di ritorno del programma stesso - fino al programma; dormire 3; fatto .
chris,

3

Un po 'confuso, ma la mia soluzione era quella di creare una funzione bash che si esegue da sola se esce con un errore

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

0

Puoi fare un ciclo mentre il tuo comando restituisce errore:

    while [ -n $(ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file) ]; do
            sleep 1;
    done;

3
Questa risposta ha bisogno di spiegazioni.
Kasperd,

@kasperd spiegazione aggiunta
Andrés Rivas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.