Co znaczy „while:;”?

27

Wiem, co to whilejest pętla. Widziałem jednak, że działa tylko z:

while [condition]
while ![condition]
while TRUE (infinite loop)

W przypadku gdy oświadczenie po whilemusi być TRUEalbo FALSE.

Istnieje wbudowane polecenie powłoki o nazwie :. Jest to opisywane jako fikcyjne polecenie, które nic nie robi, ale nie wiem, czy tutaj jest tak samo, nawet jeśli może to być TRUElub FALSE. Może to coś innego, ale co?

rekin
źródło
4
Polecenie :nic nie robi, ale zawsze kończy działanie z kodem powrotu 0. Tak samo było while true(zakładając, że twój system ma trueplik wykonywalny).
John1024,
@ John1024 Zwraca zero, chyba że ocena jego argumentów spowoduje błąd, na przykład poprzez przypisanie wartości zmiennej tylko do odczytu.
Kusalananda
3
@Kusalananda Tak, jeśli :polecenie nigdy nie zostanie wykonane, nie zwróci 0. To jednak zbyt pedantyczne.
hvd

Odpowiedzi:

50

Składnia jest następująca:

while
  first list of commands
do
  second list of commands
done

która uruchamia drugą listę poleceń w pętli, o ile pierwsza lista poleceń (czyli ostatnie uruchomienie na tej liście) zakończyła się powodzeniem.

Na pierwszej liście poleceń możesz użyć [polecenia do wykonania różnego rodzaju testów lub możesz użyć :polecenia zerowego, które nic nie robi i zwraca sukces, lub dowolnego innego polecenia.

while :; do cmd; done

Działa w cmdkółko na zawsze, jak :zawsze zwraca sukces. To jest pętla na zawsze . Zamiast tego możesz użyć truepolecenia, aby uczynić go bardziej czytelnym:

while true; do cmd; done

Ludzie woleli, :jak :zawsze było wbudowane, podczas gdy truenie było (dawno temu; większość powłok ma truewbudowane obecnie) ¹.

Inne warianty, które możesz zobaczyć:

while [ 1 ];  do cmd; done

Powyżej wywołujemy [polecenie, aby sprawdzić, czy ciąg „1” nie jest pusty (więc zawsze również prawda)

while ((1)); do cmd; done

Używanie ((...))składni Korn / bash / zsh do naśladowania while(1) { ...; }C.

Lub bardziej zawiłych podoba ci until false; do cmd; done, until ! true...

Są one czasami aliasowane:

alias forever='while :; do'

Możesz więc zrobić coś takiego:

forever cmd; done

Niewiele osób zdaje sobie sprawę, że warunkiem jest lista poleceń. Na przykład widzisz ludzi piszących:

while :; do
  cmd1
  cmd2 || break
  cmd3
done

Kiedy mogliby napisać:

while
  cmd1
  cmd2
do
  cmd3
done

Ma sens, aby była to lista, ponieważ często chcesz robić takie rzeczy, jak while cmd1 && cmd2; do...; donelisty poleceń.

W każdym razie pamiętaj, że [jest to polecenie jak każde inne (chociaż jest wbudowane w nowoczesne powłoki podobne do Bourne'a), nie musi być używane wyłącznie na listach if/ while/ untilcondition, a te listy warunków nie mają używać tego polecenia bardziej niż jakiegokolwiek innego polecenia.


¹ :jest również krótszy i przyjmuje argumenty (które ignoruje). Podczas gdy zachowanie truelub falsejest nieokreślone, jeśli przekażesz mu dowolny argument. Można więc na przykład:

while : you wait; do
  something
done

Ale zachowanie:

until false is true; do
  something
done

jest nieokreślony (choć działałoby w większości powłok / falseimplementacji).

Stéphane Chazelas
źródło
12

while :jest nieskończoną pętlą. :po prostu nic nie robi (z powodzeniem).

Jeśli więc chcesz, aby twoja powłoka zawsze wisiała bezczynnie, możesz napisać ją jako

while :
do
    :
done

Lub w jednym wierszu z ;zamiast nowych linii:while :; do :; done

while :jest zwykle używany, jeśli chcesz zrobić coś wielokrotnie bez specjalnego warunku. Można użyć continue, breakinstrukcje wewnątrz pętli ją kontrolować lub przenieść warunek zakończenia pętli jak do ... whilekonstruktu.

frostschutz
źródło
12

jednak instrukcja po chwili musi być PRAWDA lub FAŁSZ.

Nie, polecenie w części warunku może być dowolnym poleceniem (*) . Wszystkie polecenia powłoki mają pewną wartość zwracaną, a whilepętla (podobnie jak ifwarunkowa) przyjmuje wartości zwracane przez zero jako „prawda”, a wszystkie inne jako „fałsz”. (* lub lista kilku poleceń, liczy się ostatnia)

Co do tego :, instrukcja Bash wyraźnie mówi, jaki jest status zwrotu:

: [arguments]
Nie rób nic poza rozszerzaniem argumentów i przeprowadzaniem przekierowań. Status powrotu wynosi zero.

helpWbudowana jest jeszcze bardziej oczywiste:

 $ help :
 [...]
 No effect; the command does nothing
 Exit Status:
 Always succeeds.
ilkkachu
źródło
s/any command/any sequence of commands/, jak wyjaśnia Stéphane.
Toby Speight