2009-08-17 32 views
449

Tengo problemas para encontrar la combinación correcta de punto y coma y/o llaves. Me gustaría hacer esto, sino como una sola línea desde la línea de comandos:Sintaxis de una sola línea Bash infinite while loop

while [ 1 ] 
do 
    foo 
    sleep 2 
done 
+4

Reemplace las líneas nuevas con punto y coma. Lo mismo funciona para bucles for. – Tom

+19

@Tom: eso no siempre funciona. después del do, debe tener el primer comando, no un punto y coma –

Respuesta

835
while true; do foo; sleep 2; done 

Por cierto, si escribe como una línea múltiple (como se está mostrando) en el símbolo del sistema y luego llame al historial con la flecha hacia arriba, lo obtendrá en una sola línea, correctamente puntuada.

$ while true 
> do 
> echo "hello" 
> sleep 2 
> done 
hello 
hello 
hello 
^C 
$ <arrow up> while true; do echo "hello"; sleep 2; done 
+230

+1 para meter y rima. Es una gran mnemotécnica: "while * true * do * foo * sleep * too * la di da": D – Shabbyrobe

+1

"si lo escribe como una línea múltiple (como se muestra) en el símbolo del sistema y luego llama al historial con la flecha arriba, lo obtendrás en una sola línea, correctamente puntuada ". no fue cierto para mí –

+0

@VincentScheib, marque la opción 'cmdhist' si está utilizando bash? –

23

Puede usar punto y coma para separar sentencias:

$ while [ 1 ]; do foo; sleep 2; done 
+0

Me gusta esta respuesta porque explica cuándo y por qué; (punto y coma) es obligatorio. –

6

me gusta usar el punto y coma sólo para la instrucción WHILE, y la & & operador para hacer el bucle hacer más de una cosa. ..

Así que siempre lo hacen como esto

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 
+1

Bueno, el uso de '&&' en el ciclo es el mismo que en cualquier otro momento realmente no lo es. ¿Necesita que suceda lo segundo solo si sucede lo primero, y luego utiliza '&&' else ';' basta. En realidad, desea mantener el contenido de ese bucle corto y simple, lo ideal es un solo comando, por lo que una función o un script. – thecoshman

1

Si puedo dar dos ejemplos prácticos (con un poco de "emoción").

Esto escribe el nombre de todos los archivos finalizó con ".jpg" en la carpeta "img":

for f in *; do if [ "${f#*.}" == 'jpg' ]; then echo $f; fi; done 

Esto les borra:

for f in *; do if [ "${f#*.}" == 'jpg' ]; then rm -r $f; fi; done 

Sólo tratando de contribuir.

+3

Es más fácil decir: '' 'for f in * .jpg; hacer eco $ f; done''' – JKnight

+1

@JKnight - para estos ejemplos, ¿no harías ** 'ls -1 * .jpg' ** y **' rm * .jpg' ** –

+2

Ambos no son bucles infinitos y no bucles. – Marian

126

También es posible usar el comando de reposo en el estado while. Hacer un trazador de líneas que parece más limpio imho.

while sleep 2; do echo thinking; done 
+1

bueno saber !! –

+5

Bueno, esto hace más que solo cambiar la sintaxis: ejecutará el comando * después de * la suspensión. En la respuesta anterior, el comando se ejecuta de inmediato.Solo algo para tener en cuenta. – DanGordon

55

de colon es siempre "verdadero":

while :; do foo; sleep 2; done 
+11

¿Por qué el colon siempre es verdadero? – Michelle

+5

@ Pineapple Under the Sea: De la página de manual de bash: (en la sección COMANDOS DE SHELL BUILTIN) ': [argumentos]' Sin efecto; el comando no hace nada más que expandir argumentos y realizar cualquier redirección especificada. Se devuelve un código de salida cero. –

+2

esta sintaxis se recomienda como: es parte del propio shell, es decir: es un comando incorporado del shell. – avner

18

También puede hacer uso de until comando:

until ((0)); do foo; sleep 2; done 

Tenga en cuenta que, en contraste con while, until sería ejecutar los comandos en el interior el bucle siempre que la condición de prueba tenga un estado de salida que no sea cero.


El uso de un bucle while:

while read i; do foo; sleep 2; done < /dev/urandom 

El uso de un bucle for:

for ((;;)); do foo; sleep 2; done 

Otra forma usando until:

until [ ]; do foo; sleep 2; done 
+4

+1 para una solución alternativa. – glen3b

5

Un bucle infinito muy simple ..:)

while true ; do continue ; done 

Fr su pregunta sería:

while true; do foo ; sleep 2 ; done 
2

Para proceso simple observación del uso de watch lugar

0

Puede probar esto también ADVERTENCIA: esto no se debe hacer, pero ya que la la pregunta es pedir un ciclo infinito sin fin ... así es como podrías hacerlo.

while [[ 0 -ne 1 ]]; do echo "it's looping"; sleep 2; done 
+0

¿Por qué harías eso? –

+1

porque Brian Deacon, que publicó la pregunta, quería un bucle infinte. Es más de una forma de despellejar a un gato que es todo –

1

si desea que el bucle while para detenerse después de alguna condición, y su comando foo devuelve un valor distinto de cero cuando se cumple esta condición, entonces puede obtener el lazo para romper así:

while foo; do echo 'sleeping...'; sleep 5; done; 

Por ejemplo, si el comando foo está borrando cosas en lotes, y devuelve 1 cuando no queda nada por eliminar.

Esto funciona bien si tiene un script personalizado que necesita ejecutar un comando muchas veces hasta alguna condición. Escriba la secuencia de comandos para salir con 1 cuando se cumpla la condición y salga con 0 cuando se debe volver a ejecutar.

Por ejemplo, supongamos que tiene un script en Python que actualiza batch_update.py 100 filas en una base de datos y devuelve 0 si hay más de actualizar y 1 si no hay más. El siguiente comando le permitirá actualizar las filas 100 a la vez con una pausa de 5 segundos entre las actualizaciones:

while batch_update.py; do echo 'sleeping...'; sleep 5; done; 
+0

y cómo salir? –

+0

Hace que el comando 'foo' salga con el código' 1' cuando desea que se rompa el ciclo while. He actualizado mi respuesta con un ejemplo. –