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
cmdhist
opcję, 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 ; done
ale 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ć until
polecenia:
until ((0)); do foo; sleep 2; done
Zauważ, że w przeciwieństwie do while
, until
wykonywałby polecenia wewnątrz pętli, o ile warunek testowy ma status wyjścia, który nie jest równy zero.
Za pomocą while
pętli:
while read i; do foo; sleep 2; done < /dev/urandom
Za pomocą for
pę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; done
nie 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.
watch
Zamiast tego użyj prostego oglądania procesu
Używanie while
:
while true; do echo 'while'; sleep 2s; done
Korzystanie z for
pę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 foo
polecenie 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 foo
polecenie 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ć, 1
gdy warunek jest spełniony, i zakończyć, 0
kiedy powinien zostać uruchomiony ponownie.
Załóżmy na przykład, że masz skrypt w języku Python, batch_update.py
który aktualizuje 100 wierszy w bazie danych i zwraca, 0
jeśli jest więcej do zaktualizowania, a 1
jeś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;
foo
wyjście polecenia z kodem 1
kiedy 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 *.jpg
irm *.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