Cosa significa "while:;"?


27

So cos'è un whileloop. Tuttavia, l'ho visto funzionare solo con:

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

Dove la dichiarazione dopo whiledeve essere TRUEo FALSE.

C'è un comando incorporato della shell chiamato :. È descritto come un comando fittizio che non fa nulla, ma non so se sia lo stesso qui, anche se può essere TRUEo FALSE. Forse è qualcosa di diverso, ma cosa?


4
Il comando :non fa nulla ma esce sempre con il codice di ritorno 0. Quindi, è lo stesso while true(supponendo che il tuo sistema abbia un trueeseguibile).
Giovanni 1024,

@ John1024 Restituisce zero a meno che la valutazione dei suoi argomenti non provochi un errore, ad esempio assegnando un valore a una variabile di sola lettura.
Kusalananda

3
@Kusalananda Sì, se il :comando non viene mai eseguito, non restituirà 0. Secondo me è eccessivamente pedante.
hvd,

Risposte:


50

La sintassi è:

while
  first list of commands
do
  second list of commands
done

che esegue il secondo elenco di comandi in un ciclo purché il primo elenco di comandi (quindi l'ultima esecuzione in tale elenco) abbia esito positivo.

In quel primo elenco di comandi , è possibile utilizzare il [comando per eseguire vari tipi di test, oppure è possibile utilizzare il :comando null che non fa nulla e restituisce esito positivo o qualsiasi altro comando.

while :; do cmd; done

Funziona cmdall'infinito come :sempre restituisce successo. Questo è il ciclo per sempre . È possibile utilizzare trueinvece il comando per renderlo più leggibile:

while true; do cmd; done

La gente preferiva :come :era sempre stata incorporata mentre truenon lo era (molto tempo fa; la maggior parte delle shell ha truecostruito al giorno d'oggi) ¹.

Altre varianti che potresti vedere:

while [ 1 ];  do cmd; done

Sopra, stiamo chiamando il [comando per verificare se la stringa "1" non è vuota (quindi sempre anche vera)

while ((1)); do cmd; done

Utilizzando la ((...))sintassi Korn / bash / zsh per imitare il while(1) { ...; }di C.

O più contorti come until false; do cmd; done, until ! true...

A volte sono aliasati come:

alias forever='while :; do'

Quindi puoi fare qualcosa del tipo:

forever cmd; done

Poche persone si rendono conto che la condizione è un elenco di comandi. Ad esempio, vedi persone che scrivono:

while :; do
  cmd1
  cmd2 || break
  cmd3
done

Quando avrebbero potuto scrivere:

while
  cmd1
  cmd2
do
  cmd3
done

Ha senso che sia un elenco poiché spesso si desidera fare cose come quelle while cmd1 && cmd2; do...; doneche sono anche liste di comandi.

In ogni caso, si noti che [è un comando come un altro (sebbene sia incorporato nelle moderne shell tipo Bourne), non deve essere utilizzato esclusivamente negli elenchi delle condizioni if/ while/ untile tali elenchi delle condizioni non hanno per usare quel comando più di ogni altro comando.


¹ :è anche più breve e accetta argomenti (che ignora). Mentre il comportamento di trueo falsenon è specificato se si passa qualsiasi argomento. Quindi uno può fare per esempio:

while : you wait; do
  something
done

Ma il comportamento di:

until false is true; do
  something
done

non è specificato (anche se funzionerebbe nella maggior parte delle shell / falseimplementazioni).


12

while :è un ciclo infinito. :semplicemente non fa nulla (con successo).

Quindi se vuoi che la tua shell rimanga appesa per sempre senza fare nulla, puoi scriverla come

while :
do
    :
done

O in una sola riga con ;anziché nuove righe:while :; do :; done

while :viene di solito utilizzato se si desidera fare qualcosa ripetutamente senza una condizione speciale allegata. È possibile utilizzare continue, breakle dichiarazioni all'interno del ciclo di controllarlo o per spostare la condizione alla fine del ciclo come un do ... whilecostrutto.


12

tuttavia, la frase dopo deve essere TRUE o FALSE.

No, il comando nella parte condizione può essere qualsiasi comando (*) . Tutti i comandi di shell hanno un valore di ritorno e il whileciclo (così come il ifcondizionale) assume valori di ritorno di zero come "vero" e tutti gli altri come "falso". (* o un elenco di più comandi, l'ultimo conta)

Per quanto riguarda :, il manuale di Bash dice chiaramente qual è lo stato di ritorno di questo:

: [arguments]
Non fare altro che espandere gli argomenti ed eseguire reindirizzamenti. Lo stato di ritorno è zero.

L' helpintegrato è ancora più chiaro:

 $ help :
 [...]
 No effect; the command does nothing
 Exit Status:
 Always succeeds.

s/any command/any sequence of commands/, come chiarisce Stéphane.
Toby Speight,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.