skrypt bash: powtórz polecenie, jeśli zwróci błąd

23

Chciałbym utworzyć pętlę, która powtarza transfer ncftp, jeśli zwraca błąd.

Nie jestem pewien, w jaki sposób można użyć zmiennej kodu wyjścia w pętli. Czy coś takiego mogłoby działać?

until [$? == 0]; do
    ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file
done
Roy
źródło

Odpowiedzi:

40

Podstawę tej eleganckiej pętli znalazłem gdzie indziej na serwerze serverault. Okazuje się, że nie ma potrzeby zapisywania kodu wyjścia, ponieważ można przetestować bezpośrednio na samym poleceniu;

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
źródło
8

Prawie. Prawdopodobnie lepiej jest zapisać wartość zwracaną jako zmienną, aby można było ją wstępnie ustawić przed pętlą. W przeciwnym razie będzie to miało wpływ na polecenie ostatniego uruchomienia.

Możesz także zawiesić sleeptam, aby nie odradzał się zbyt szybko.

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
źródło
Myślę, że zapomniałem przekazać kod wyjścia do zmiennej RET, ale mam pomysł. Moje główne pytanie dotyczy tego, kiedy zostanie oceniona klauzula till? W C nie będzie to oceniane aż do pierwszego uruchomienia pętli, w którym to przypadku moja pętla powinna działać. Twoje jest jednak jeszcze lepsze, ponieważ pozwala na wykonywanie poleceń pośrednich, takich jak sen. Dzięki!
Roy
Dobrze zauważony. Zredagowałem to. Klauzula zostanie oceniona przed pierwszym uruchomieniem. Wcześniej używałby kodu powrotu dowolnego poprzedniego polecenia. Podwójne równości nie są wymuszane przez Bash, ale jest to dobra praktyka w użyciu.
Dan Carley,
== jest równość strun nie numeryczne, chociaż nie sądzę, jest to ważne w tym przypadku ...
Kyle Brandt
Pojedyncze i podwójne są równe. Ale lepiej byłoby użyć równości liczb całkowitych teraz, kiedy o tym wspominasz.
Dan Carley,
1
Nie musisz testować numeru kodu powrotu - możesz po prostu przetestować kod powrotu samego programu - aż do programu; śpij 3; gotowy .
Chris
3

Trochę hacky, ale moim rozwiązaniem było po prostu utworzenie funkcji bash, która uruchomi się sama, jeśli zakończy się niepowodzeniem

function retry { the_command_you_want && echo "success" || (echo "fail" && retry) }; retry
Qwertie
źródło
0

Możesz wykonać pętlę, gdy twoje polecenie zwróci błąd:

    while [ -n $(ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file) ]; do
            sleep 1;
    done;
Andrés Rivas
źródło
3
Ta odpowiedź wymaga wyjaśnienia.
kasperd
Dodano wyjaśnienie @kasperd
Andrés Rivas,