Was bedeutet "while:;"?

27

Ich weiß, was eine whileSchleife ist. Ich habe jedoch nur gesehen, dass es funktioniert mit:

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

Wo die Aussage danach whileentweder TRUEoder sein muss FALSE.

Es gibt einen Shell-Befehl namens builtin :. Es wird als Dummy-Befehl beschrieben, der nichts tut, aber ich weiß nicht, ob es hier dasselbe ist, auch wenn es sein kann TRUEoder nicht FALSE. Vielleicht ist es etwas anderes, aber was?

Hai
quelle
4
Der Befehl :führt nichts aus, sondern wird immer mit dem Rückkehrcode 0 beendet. Es ist also dasselbe wie zuvor while true(vorausgesetzt, Ihr System hat eine trueausführbare Datei).
John1024
@ John1024 Es wird null zurückgegeben, es sei denn, die Auswertung seiner Argumente verursacht einen Fehler, indem beispielsweise einer schreibgeschützten Variablen ein Wert zugewiesen wird.
Kusalananda
3
@Kusalananda Ja, wenn der :Befehl nie ausgeführt wird, wird er keine 0 zurückgeben. Das ist meiner Meinung nach jedoch zu umständlich.
HDV

Antworten:

50

Die Syntax lautet:

while
  first list of commands
do
  second list of commands
done

Dies führt die zweite Befehlsliste in einer Schleife aus, solange die erste Befehlsliste (also die letzte Ausführung in dieser Liste) erfolgreich ist.

In dieser ersten Liste von Befehlen können Sie den [Befehl verwenden, um verschiedene Arten von Tests durchzuführen, oder Sie können den :Befehl null verwenden, der nichts tut und Erfolg zurückgibt, oder einen anderen Befehl.

while :; do cmd; done

Läuft cmdfür :immer und ewig und bringt immer wieder Erfolg. Das ist die für immer Schleife. Sie können truestattdessen den Befehl verwenden, um die Lesbarkeit zu verbessern:

while true; do cmd; done

Früher wurde bevorzugt, :wie :immer, während truees nicht war (vor langer Zeit; die meisten Muscheln haben trueheutzutage gebaut) ¹.

Andere Varianten, die Sie vielleicht sehen:

while [ 1 ];  do cmd; done

Oben rufen wir den [Befehl auf, um zu testen, ob die Zeichenfolge "1" nicht leer ist (also auch immer wahr).

while ((1)); do cmd; done

Verwenden der Korn / bash / zsh- ((...))Syntax zur Nachahmung while(1) { ...; }von C.

Oder mehr gewunden diejenigen mögen until false; do cmd; done, until ! true...

Diese sind manchmal voreingenommen wie:

alias forever='while :; do'

Sie können also Folgendes tun:

forever cmd; done

Nur wenigen ist klar, dass es sich bei der Bedingung um eine Liste von Befehlen handelt. Zum Beispiel sehen Sie Leute, die schreiben:

while :; do
  cmd1
  cmd2 || break
  cmd3
done

Wann sie hätten schreiben können:

while
  cmd1
  cmd2
do
  cmd3
done

Es ist sinnvoll, wenn es sich um eine Liste handelt, da Sie häufig auch Dinge tun möchten, while cmd1 && cmd2; do...; donedie Befehlslisten sind.

In jedem Fall beachten Sie, dass [ein Befehl wie jedes andere ist (obwohl es ist eingebaut in modernen Bourne-wie Muscheln), ist es nicht nur in den verwendet werden müssen if/ while/ untilKonditionslisten, und diese Konditionslisten haben nicht um diesen Befehl mehr als jeden anderen Befehl zu verwenden.


¹ :ist auch kürzer und akzeptiert Argumente (die ignoriert werden). Während das Verhalten von trueoder falsenicht angegeben ist, wenn Sie ein Argument übergeben. So kann man zum Beispiel tun:

while : you wait; do
  something
done

Aber das Verhalten von:

until false is true; do
  something
done

ist nicht spezifiziert (obwohl es in den meisten Shell / falseImplementierungen funktionieren würde ).

Stéphane Chazelas
quelle
12

while :ist eine Endlosschleife. :macht einfach nichts (erfolgreich).

Wenn Sie also möchten, dass Ihre Shell für immer hängt und nichts tut, können Sie sie wie folgt schreiben

while :
do
    :
done

Oder in einer einzelnen Zeile mit ;anstelle von Zeilenumbrüchen:while :; do :; done

while :wird normalerweise verwendet, wenn Sie wiederholt etwas tun möchten, ohne dass eine besondere Bedingung vorliegt. Sie könnten verwenden continue, breakAnweisungen innerhalb der Schleife um ihn zu steuern oder den Zustand bis zum Ende der Schleife wie ein bewegen do ... whileKonstrukt.

Frostschutz
quelle
12

Die Anweisung nach while muss jedoch entweder TRUE oder FALSE sein.

Nein, der Befehl im Bedingungsteil kann ein beliebiger Befehl (*) sein . Alle Shell-Befehle haben einen bestimmten Rückgabewert, und die whileSchleife (sowie die ifBedingung) nimmt Rückgabewerte von Null als "wahr" und alle anderen als "falsch" an. (* oder eine Liste mit mehreren Befehlen, der letzte zählt)

Was :, Bash Anleitung sagt , was eindeutig der Rückgabestatus das heißt:

: [arguments]
Führen Sie nichts weiter aus, als Argumente zu erweitern und Umleitungen durchzuführen. Der Rückgabestatus ist Null.

Das helpeingebaute ist noch deutlicher:

 $ help :
 [...]
 No effect; the command does nothing
 Exit Status:
 Always succeeds.
ilkkachu
quelle
s/any command/any sequence of commands/, wie Stéphane klar macht.
Toby Speight