Manual de Bash: bucles y estructuras
Anidar bucles
En general, en Bash es posible anidar todo tipo de bucles, estructuras y condiciones.
Estructuras condicionales if
Las estructuras condicionales if permiten que nuestros scripts se comporten de una forma u otra según la condición que especifiquemos, siendo condición un comando test. La sintaxis es:
if condicion1; then Bloque1 elif condicion2; then Bloque2 else Bloque3 fi
En el siguiente ejemplo pedimos al usuario un número que se almacena en la variable $input. Dependiendo de si el número es menor, igual o mayor que 5, el script se comporta de una forma u otra. Si el usuario no introduce nada o introduce una cadena de texto, se ejecutará lo que hay tras else, pues ninguna de las condiciones anteriores se cumple.
#!/bin/bash echo "Introduzca un numero: " read input if [ $input -lt 5 ]; then echo "El numero era menor que 5" elif [ $input -eq 5 ]; then echo "El numero era 5" elif [ $input -gt 5 ]; then echo "El numero era mayor que 5" else echo "No introdujo un numero" fi
En el siguiente ejemplo, primero comprobamos que nos han pasado dos argumentos (el archivo donde buscar y la cadena de búsqueda): si no es así, le indicamos al usuario cómo debe ejecutar el script y salimos. A continuación comprobamos que el archivo existe: si no es así, advertimos y salimos. Una vez verificadas estas dos condiciones, mediante cat y el pipe, grep cuenta el número de veces que el valor de $BUSQUEDA está en el archivo, que queda guardado en $NUM_VECES.
#!/bin/bash if [ $# -ne 2 ]; then echo "Necesito dos argumentos, el primero" echo "es el archivo donde debo buscar y" echo "el segundo es lo que quieres que busque." echo " " echo "Uso: $0 <archivo> <patron_busqueda>" echo " " exit fi ARCHIVO=$1 BUSQUEDA=$2 if [ ! -e $ARCHIVO ]; then echo "El archivo no existe" exit fi NUM_VECES='cat "$ARCHIVO" | grep --count "$BUSQUEDA"' if [ $NUM_VECES -eq 0 ]; then echo "El patron de busqueda \"$BUSQUEDA\" no fue encontrado" echo "en el archivo $ARCHIVO " else echo "El patron de busqueda \"$BUSQUEDA\" fue encontrado" echo "en el archivo $ARCHIVO $NUM_VECES veces" fi
Estructura case
La estructura case sirve para actuar de una u otra manera en función del valor de una variable: esto podríamos hacerlo con if, pero case es más eficiente y cómodo. La sintaxis es:
case $VARIABLE in valor1) Bloque 1 ;; valor2) Bloque 2 ;; ... *) Bloque default ;; esac
Si $VARIABLE no coincide con ninguno de los valores valor1, valor2... sí coindirá con el comodín *, ejecutándose el Bloque default. Veamos un ejemplo:
#!/bin/bash if [ $# -lt 1 ]; then echo "Error. Esperaba al menos un parametro" exit 1 fi case $1 in windows) echo "El logo de windows es una ventana" exit 0 ;; mac) echo "El logo de mac es una manzana" exit 0 ;; linux) echo "El logo de linux es un pinguino" exit 0 ;; *) echo "Logo sin definir" exit 1 ;; esac
Bucles for
El bucle for viene a solucionar el problema de "Para cada uno de
los elementos siguientes, quiero que mi script haga esto". El bucle for
ejecuta las sentencias de Bloque tantas veces como elementos haya en
LISTA: la primera vez VARIABLE valdrá el primer elemento de la
lista, la segunda vez VARIABLE valdrá el segundo elemento de la lista,
y así sucesivamente. El elemento LISTA del bucle for puede ser
una variable que contenga una lista de elementos:
lista = "pedro pepe juan jose"
for i in $lista; do
... una lista de elementos:
for i in pedro pepe juan jose; do
... una lista de archivos dada utilizando comodines:
for i in $DIR/.*; do
... o un comando tal que su salida sea una lista de elementos:
for i in 'ls'; do
La sintaxis del bucle for es:
for VARIABLE in LISTA ; do Bloque done
Veamos un ejemplo. Si ejecutamos el siguiente script:
#!/bin/bash for i in pedro pepe juan jose; do echo "Hola $i" done
obtenemos:
Hola pedro Hola pepe Hola juan Hoja jose
El siguiente ejemplo lista los archivos y directorios ocultos. Una vez comprobado que la cadena que se le ha pasado como argumento no tiene longitud cero, que existe y que es un directorio, lista cada archivo que pertenezca a la lista, es decir, que verifique que su primer carácter es un punto (.):
#!/bin/bash DIR=$1 if [ -z $DIR ]; then echo "El primer argumento debe tener longitud mayor que 0" exit 1 fi if [ ! -d $DIR ]; then echo "El directorio debe existir y ser un directorio" exit 1 fi for i in $DIR/.*; do echo "Encontrado el elemento oculto $i" done echo "Finalizado"
En el bucle for podemos usar break para salir del bucle en cualquier momento.
Bucles while
El otro tipo de bucle posible en los scripts de bash es el bucle while. Este bucle viene a solucionar el problema de "quiero que mi script haga esto mientras que se dé esta condición". Su sintaxis es:
while test CONDICION; do Bloque done
En el siguiente ejemplo la condición para que el bucle se siga ejecutando es "que $j valga menos de 10", y en cada ciclo sumamos 1 a la variable $j:
#!/bin/bash j=0 while [ $j -lt 10 ]; do echo "j vale $j" j=$[$j+1] done
En el bucle while también podemos usar break para salir del bucle en cualquier momento. En el siguiente ejemplo la condición se cumple siempre (test 1 siempre retornará TRUE), pero break hará que termine el bucle cuando el número introducido sea igual a $MINUM.
#!/bin/bash MINUM=8 while [ 1 ]; do echo "Introduzca un numero: " read USER_NUM if [ $USER_NUM -lt $MINUM ]; then echo "El numero introducido es menor que el mio" echo " " elif [ $USER_NUM -gt $MINUM ]; then echo "El numero introducido es mayor que el mio" echo " " elif [ $USER_NUM -eq $MINUM ]; then echo "Acertaste: Mi numero era $MINUM" break fi done echo "El script salio del bucle. Finalizado."
Deja un comentario