Składnia dla jednowierszowej pętli Bash nieskończonej podczas pętli


633

Mam problem z wymyśleniem odpowiedniej kombinacji średników i / lub nawiasów klamrowych. Chciałbym to zrobić, ale jako jeden wiersz z wiersza poleceń:

while [ 1 ]
do
    foo
    sleep 2
done

4
zamień znaki nowej linii na średniki. To samo działa dla pętli.
Tom

23
@Tom: to nie zawsze działa. po zakończeniu musisz mieć pierwsze polecenie, a nie średnik
Stefano Borini,

Odpowiedzi:


1230
while true; do foo; sleep 2; done

Nawiasem mówiąc, jeśli wpiszesz go jako multilinię (jak pokazano) w wierszu polecenia, a następnie wywołasz historię ze strzałką w górę, otrzymasz ją w jednym wierszu, poprawnie interpunkcyjnym.

$ while true
> do
>    echo "hello"
>    sleep 2
> done
hello
hello
hello
^C
$ <arrow up> while true; do    echo "hello";    sleep 2; done

2
„jeśli wpiszesz go jako multilinię (jak pokazano) w wierszu polecenia, a następnie wywołasz historię ze strzałką w górę, otrzymasz ją w jednym wierszu, poprawnie interpunkcyjnym.” nie było dla mnie prawdą.
Vincent Scheib

@VincentScheib, zaznacz cmdhistopcję, jeśli używasz bash?
Alok Singhal

Świetny! Działa doskonale na Mavericks (Mac OS-X 10.9) i pozwala mi utrzymać działanie VPN. Openconnect rozłącza się po kilku godzinach z błędem błędnego pliku cookie. Więc umieściłem polecenie openconnect w skrypcie powłoki, sudo su, aby zostać rootem, i używam tej linii cmd: while true; do sh /Users/myuser/bin/vpn ; done
Blisterpeanuts

170

Możliwe jest również użycie polecenia uśpienia w stanie while. Sprawiając, że jednopowłokowy wygląda bardziej czysty imho.

while sleep 2; do echo thinking; done

16
Cóż, to coś więcej niż tylko zmiana składni - wykona polecenie po uśpieniu. W poprzedniej odpowiedzi polecenie zostało wykonane natychmiast. Po prostu coś do odnotowania.
DanGordon

@DanGordon while echo thinking ; do sleep 2 ; done Oczywiście, jeśli polecenie [while] nie powiedzie się, pętla zostanie zamknięta, więc musisz, while echo thinking || true ; do sleep 2 ; doneale wrócisz dowhile true ; ...
Brian Carcich,

69

Dwukropek jest zawsze „prawdziwy”:

while :; do foo; sleep 2; done

15
dlaczego dwukropek jest zawsze prawdziwy?
Jürgen Paul,

8
@Pineapple Under the Sea: Ze strony podręcznika użytkownika bash: (w sekcji KOMENDY WBUDOWANE) : [arguments] Bez efektu; polecenie nie robi nic poza rozszerzaniem argumentów i wykonywaniem określonych przekierowań. Zwracany jest zerowy kod wyjścia.
Adrian W

2
ta składnia jest zalecana, ponieważ: jest częścią samej powłoki, tzn .: jest wbudowanym poleceniem powłoki.
avner

@analytik, więc mówisz, że to plus lub minus? ;-)
Brian Carcich

33

Możesz użyć średników do oddzielenia instrukcji:

$ while [ 1 ]; do foo; sleep 2; done

3
Podoba mi się ta odpowiedź, ponieważ wyjaśnia, kiedy i dlaczego; (średnik) jest wymagany.
Pan AndreasGeo

29

Możesz także użyć untilpolecenia:

until ((0)); do foo; sleep 2; done

Zauważ, że w przeciwieństwie do while, untilwykonywałby polecenia wewnątrz pętli, o ile warunek testowy ma status wyjścia, który nie jest równy zero.


Za pomocą whilepętli:

while read i; do foo; sleep 2; done < /dev/urandom

Za pomocą forpętli:

for ((;;)); do foo; sleep 2; done

Innym sposobem jest użycie until:

until [ ]; do foo; sleep 2; done

To until ((0)); do foo; sleep 2; donenie wydaje się działać. Ciągły nieskończony.
030

11

Bardzo prosta nieskończona pętla .. :)

while true ; do continue ; done

Fr twoje pytanie brzmiałoby:

while true; do foo ; sleep 2 ; done

8

Lubię używać średników tylko do instrukcji WHILE, a operator && sprawia, że ​​pętla robi więcej niż jedną rzecz ...

Więc zawsze tak to robię

while true ; do echo Launching Spaceship into orbit && sleep 5s && /usr/bin/launch-mechanism && echo Launching in T-5 && sleep 1s && echo T-4 && sleep 1s && echo T-3 && sleep 1s && echo T-2 && sleep 1s && echo T-1 && sleep 1s && echo liftoff ; done

1
Cóż, użycie &&pętli jest takie samo jak w każdym innym przypadku, prawda? Czy potrzebujesz, aby druga rzecz się wydarzyła tylko wtedy, gdy pierwsza się zdarzy, to użyj &&innego ;. Naprawdę chcesz, aby zawartość tej pętli była krótka i prosta, najlepiej tylko jedno polecenie, a więc funkcja lub skrypt.
thecoshman


6

Używanie while:

while true; do echo 'while'; sleep 2s; done

Korzystanie z forpętli:

for ((;;)); do echo 'forloop'; sleep 2; done

Korzystanie Recursion, (nieco inaczej niż powyżej, przerwanie klawiatury nie zatrzyma tego)

list(){ echo 'recursion'; sleep 2; list; } && list;

5

Jeśli chcesz, aby pętla while zatrzymała się po spełnieniu pewnego warunku, a twoje foopolecenie zwraca wartość niezerową po spełnieniu tego warunku, możesz uzyskać przerwanie pętli w następujący sposób:

while foo; do echo 'sleeping...'; sleep 5; done;

Na przykład, jeśli foopolecenie usuwa rzeczy partiami, a zwraca 1, gdy nie ma już nic do usunięcia.

Działa to dobrze, jeśli masz niestandardowy skrypt, który musi uruchamiać polecenie wiele razy, aż do spełnienia określonych warunków. Piszemy skrypt, aby zakończyć, 1gdy warunek jest spełniony, i zakończyć, 0kiedy powinien zostać uruchomiony ponownie.

Załóżmy na przykład, że masz skrypt w języku Python, batch_update.pyktóry aktualizuje 100 wierszy w bazie danych i zwraca, 0jeśli jest więcej do zaktualizowania, a 1jeśli ich nie ma. Następujące polecenie pozwoli ci aktualizować wiersze 100 jednocześnie z uśpieniem przez 5 sekund między aktualizacjami:

while batch_update.py; do echo 'sleeping...'; sleep 5; done;

i jak byś wyszedł?
AK_

Państwo dokonać foowyjście polecenia z kodem 1kiedy chcesz pętli while do złamania. Zaktualizowałem swoją odpowiedź za pomocą przykładu.
Yep_It's_Me

2

Czy mogę podać dwa praktyczne przykłady (z odrobiną „emocji”).

Spowoduje to zapisanie nazwy wszystkich plików zakończonych „.jpg” w folderze „img”:

for f in *; do if [ "${f#*.}" == 'jpg' ]; then echo $f; fi; done

Spowoduje to ich usunięcie:

for f in *; do if [ "${f#*.}" == 'jpg' ]; then rm -r $f; fi; done

Próbuję tylko pomóc.


1
@JKnight - dla tych przykładów nie zrobiłbyś ls -1 *.jpgirm *.jpg
Kevin Fegan

2
Oba nie są nieskończonymi pętlami i nie są pętlami while.
Marian

2

Możesz także tego spróbować OSTRZEŻENIE: nie powinieneś tego robić, ale ponieważ pytanie dotyczy nieskończonej pętli bez końca ... tak możesz to zrobić.

while [[ 0 -ne 1 ]]; do echo "it's looping";   sleep 2; done

Dlaczego miałbyś to zrobić?
gniourf_gniourf

2
ponieważ Brian Deacon, który opublikował pytanie, chciał jak nieskończona pętla. To więcej niż jeden sposób na
skórowanie
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.