Bir kabuk komutu başarısız olana kadar tekrar tekrar çalıştırılsın mı?


191

Güvenilmez bir şekilde başarısız olan bulanık bir test yazdım . Bazı hata ayıklama kodu ekledim, ancak şimdi hata ayıklama çıktısını toplamak böylece başarısız olana kadar testi çalıştırmak istiyorum.

Testi kullanarak ben çalıştırabilirsiniz böylece kurdum:

./runtest

Şu anki çözümüm bir untilfailsenaryo yazmak :

#!/bin/bash
$@
while [ $? -eq 0 ]; do
    $@
done

Sonra kullanın:

untilfail ./runtest

Daha basit bir çözüm var mı?


11
Yan not: alışılmış şekilde "$ @" alıntı.
jordanm

Yanıtlar:


328

while yürütmek için bir komut alır, böylece daha basit kullanabilirsiniz

while ./runtest; do :; done

Bu, sıfır dışında bir çıkış kodu ./runtestdöndürdüğünde (genellikle hata olduğunu gösteren) döngüyü durduracaktır .

Mevcut çözümünüzü daha da basitleştirmek için, kadar başarısız betiğinizi şöyle görünecek şekilde değiştirmeniz gerekir:

#!/bin/bash

while "$@"; do :; done

Ve sonra zaten kullandığınız komutla çağırabilirsiniz:

untilfail ./runTest --and val1,val2 -o option1 "argument two"

25
Bunun [bir komut olduğunu belirtmek de iyidir . Yeni kullanıcılarla yaygın bir yanlış anlama [parçasıdır ifve whilesözdizimi.
jordanm

2
Başarısız olmadan önce kaç kez koştuğunu nasıl anlayabilirim?
GrantJ

13
@ GrantJ: Aslında çok basit. Döngüden count=0önce koyun , sonra döngü yerine :(no-op) koyun (( count++ ))- bu sayacı artırır.
nneonneo

14
Bir verimlilik hack: Eğer bir sistemde sayve bir hoparlörde iseniz, while ./runtest; do :; done && say test faileddurursa haberdar olmak için kullanabilirsiniz
Schneems

5
@Schneems: macOS'a sayözgü olduğunu belirtmeye değer .
nneonneo

13

Karmaşık bir boru hattını bir kabuk komut dosyasına veya işleve sarmak istemiyorsanız, bu işe yarar:

while true; do 
  curl -s "https:..." | grep "HasErrors.:true"
  if [[ "$?" -ne 0 ]]; then 
    break
  fi
  sleep 120
done

Bu durumda HTTP isteği her zaman 200 değerini döndürür ancak "HasErrors" özniteliğine sahip bazı JSON döndürür: bir hata olduğunda true.


1

Kabuk yeniden deneme mantığı her yerde çoğaltılan bir sistemde benzer bir sorun yaşadım, "yeniden deneme" adı verilen bu sorunu çözmek için özel bir araç yaptım:

retry --until=fail ./runtest

Daha karmaşık bir örnek:

retry --until=fail --message="test succeeded" --delay=1 ./runtest

Aracı https://github.com/minfrin/retry adresinde bulabilirsiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.