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
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
Odpowiedzi:
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
cmdhistopcję, jeśli używasz bash?
while true; do sh /Users/myuser/bin/vpn ; done
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
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 ; ...
Dwukropek jest zawsze „prawdziwy”:
while :; do foo; sleep 2; done
: [arguments] Bez efektu; polecenie nie robi nic poza rozszerzaniem argumentów i wykonywaniem określonych przekierowań. Zwracany jest zerowy kod wyjścia.
Możesz użyć średników do oddzielenia instrukcji:
$ while [ 1 ]; do foo; sleep 2; done
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
until ((0)); do foo; sleep 2; donenie wydaje się działać. Ciągły nieskończony.
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
&&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.
watchZamiast tego użyj prostego oglądania procesu
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;
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;
foowyjście polecenia z kodem 1kiedy chcesz pętli while do złamania. Zaktualizowałem swoją odpowiedź za pomocą przykładu.
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.
ls -1 *.jpgirm *.jpg
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