¡Cuidado con los bucles infinitos!
La capacidad de hacer bucles es una característica muy poderosa de los scripts de bash. Los bucles tienen una variedad de casos de uso.
En este tutorial, explorarás las tres diferentes estructuras de bucles de bash. También aprenderás a utilizar bucles para recorrer elementos de un array.
Además, aprenderás a utilizar las sentencias break y continue para controlar los bucles, y finalmente, aprenderás a crear bucles infinitos.
Bucles For en Bash
Los bucles for son uno de los tres tipos diferentes de estructuras de bucle que puedes utilizar en bash. Hay dos estilos diferentes para escribir un bucle for.
- Bucles for en bash al estilo C
- Uso del bucle for en una lista/rango de elementos
Bucles for en bash al estilo C
Si estás familiarizado con un lenguaje de programación similar a C o C++, entonces reconocerás la siguiente sintaxis del bucle for:
for ((inicializar ; condición ; incremento)); do
[COMANDOS]
done
Utilizando la sintaxis de estilo C antes mencionada, el siguiente bucle for imprimirá “Hola amigo” diez veces:
for ((i = 0 ; i < 10 ; i++)); do
echo "Hola amigo"
done
El bucle for primero inicializa la variable entera i a cero y luego comprueba la condición (i <10); si es verdadera, entonces el bucle ejecuta la línea echo “Hello Friend” e incrementa la variable i en 1, y luego el bucle se ejecuta una y otra vez hasta que i ya no es menor que 10.
team@itsfoss:~$ bash hola.sh
Hola amigo
Hola amigo
Hola amigo
Hola amigo
Hola amigo
Hola amigo
Hola amigo
Hola amigo
Hola amigo
Hola amigo
Lista/rango de bucles For en Bash
También existe otra variación de la sintaxis del bucle for que resulta especialmente útil si se trabaja con una lista de archivos (o cadenas), un rango de números, matrices, la salida de un comando, etc. La sintaxis del bucle for de lista/rango tiene la siguiente forma:
for elemento in [LISTA]; do
[COMANDOS]
done
Por ejemplo, el siguiente bucle for hace exactamente lo mismo que el bucle for de estilo C que habías creado en la sección anterior:
for i in {1..10}; do
echo "Hello Friend"
done
El script var.sh de abajo mostrará todos los archivos y directorios que existen bajo el directorio /var:
#!/bin/bash
for i in /var/*; do
echo $i
done
A continuación se muestra un ejemplo de salida cuando se ejecuta el script var.sh:
team@itsfoss:~$ ./var.sh
/var/backups
/var/cache
/var/crash
/var/lib
/var/local
/var/lock
/var/log
/var/mail
/var/opt
/var/run
/var/snap
/var/spool
/var/tmp
Bucles While en Bash
El bucle while es otro bucle popular e intuitivo que puedes utilizar en los scripts de bash. La sintaxis general de un bucle while es la siguiente:
while [ condición ]; do
[COMANDOS]
done
Por ejemplo, el siguiente script 3×10.sh utiliza un bucle while que imprimirá los diez primeros múltiplos del número tres:
#!/bin/bash
num=1
while [ $num -le 10 ]; do
echo $(($num * 3))
num=$(($num+1))
done
Aquí está la salida del script anterior:
team@itsfoss:~$ ./3x10.sh
3
6
9
12
15
18
21
24
27
30
Primero inicializa la variable num a 1; luego, el bucle while se ejecutará mientras num sea menor o igual a 10. Dentro del cuerpo del bucle while, el comando echo imprime de num multiplicado por tres y luego incrementa num en 1.
Bucle Until en Bash
Si vienes de un entorno C/C++, puede que estés buscando un bucle do-while pero éste no existe en bash.
Hay otro tipo de bucle que existe en bash. El bucle until sigue la misma sintaxis que el bucle while:
until [ condición ]; do
[COMANDOS]
Done
La diferencia clave entre el bucle until y el bucle while está en la condición de prueba. Un bucle while seguirá ejecutándose mientras la condición de prueba sea verdadera; por el contrario, un bucle until seguirá ejecutándose mientras la condición de prueba sea falsa.
Por ejemplo, puedes crear fácilmente el script 3×10.sh con un bucle until en lugar de un bucle while; el truco aquí es negar la condición de prueba:
#!/bin/bash
num=1
until [ $num -gt 10 ]; do
echo $(($num * 3))
num=$(($num+1))
done
Observe que la negación de la condición de prueba [ $num -le 10 ]; es [ $num -gt 10 ]
Más información sobre los bucles en los scripts bash
Ahora que estás familiarizado con los bucles en los scripts de bash
Imprimir el contenido de un array en bash
Si estás siguiendo esta serie de tutoriales desde el principio, deberías estar familiarizado con los arrays en bash.
Los bucles For suelen ser la opción más popular cuando se trata de iterar sobre los elementos de un array.
Por ejemplo, el siguiente script primo.sh itera e imprime cada elemento de la matriz prime:
#!/bin/bash
prime=(2 3 5 7 11 13 17 19 23 29)
for i in "${prime[@]}"; do
echo $i
done
Esta es la salida del script primo.sh:
team@itsfoss:~$ ./prime.sh
2
3
5
7
11
13
17
19
23
29
Uso de Break y Continue en bucles bash
La sentencia break finaliza la ejecución de un bucle y pasa el control del programa al siguiente comando o instrucción que sigue al bucle.
Por ejemplo, el siguiente bucle sólo imprimiría los números del uno al tres:
for ((i=1;i<=10;i++)); do
echo $i
if [ $i -eq 3 ]; then
break
fi
done
También puedes utilizar una sentencia continue para saltarse una iteración del bucle. El bucle continúa y pasa a la siguiente iteración, pero los comandos después de las sentencias continue se saltan en esa iteración parcial.
Por ejemplo, el siguiente script impar.sh sólo imprimiría los números impares del uno al diez, ya que se salta todos los números pares:
#!/bin/bash
for ((i=0;i<=10;i++)); do
if [ $(($i % 2)) -ne 1 ]; then
continue
fi
echo $i
done
Esta es la salida que imprime los números impares:
team@itsfoss:~$ ./odd.sh
1
3
5
7
9
Bucles infinitos en bash
Un bucle infinito es un bucle que se ejecuta eternamente; esto ocurre cuando la condición de prueba del bucle es siempre verdadera.
En la mayoría de los casos, los bucles infinitos son producto de un error lógico humano.
Por ejemplo, alguien que quiera crear un bucle que imprima los números del 1 al 10 en orden descendente puede acabar creando el siguiente bucle infinito por error:
for ((i=10;i>0;i++)); do
echo $i
hecho
El problema es que el bucle sigue incrementando la variable i en 1. Para solucionarlo, hay que cambiar i++ por i- de la siguiente manera:
for ((i=10;i>0;i--)); do
echo $i
done
En algunos casos, puedes querer crear intencionalmente bucles infinitos para esperar que se cumpla una condición externa en el sistema. Puedes crear fácilmente un bucle for infinito de la siguiente manera:
for ((;;)); do
[COMANDOS]
done
Si en cambio quieres crear un bucle while infinito, entonces puedes crearlo de la siguiente manera:
while [ true ]; do
[COMANDOS]
done
¡Impresionante! Con esto llegamos al final de este tutorial de la serie para principiantes de Bash. ¡Espero que hayas disfrutado haciendo bucles en bash!
Permanece atento al próximo capítulo en el que aprenderás a reutilizar código en tus scripts de bash creando funciones.