Aprende GNU/Linux 14

Aprendiendo shell scripting en Linux: condicionales y bucles

Aprendiendo shell scripting en Linux: condicionales y buclesLos scripts son mucho más que simples interpretes de comandos, estos poseen muchas características propias de los lenguajes de programación, y como en todo lenguaje de programación, es posible y necesario utilizar condicionales y bucles . Tanto los condicionales como los bucles son los cimientos de cualquier lenguaje de programación, y en el caso de los scripts, nos van a dotar de lo necesario para conseguir mucha más profundidad y complejidad, además de permitirnos realizar tareas que de otra forma seria imposible.

Antes de empezar

Antes de empezar con los condicionales y con los bucles es conveniente dedicarle un minuto a unos comandos que nos van a ayudar con la elaboración de ambos, no voy a dar ejemplos exclusivos de estas instrucciones, ya que voy a requerirlos en los ejemplos de más adelante y sera entonces cuando se comprenda su funcionamiento. Los comandos en cuestión son los siguientes:

Comando Break

El comando break permite interrumpir un bucle, cuando un bucle llega a una instrucción break, el script continua después del done del mismo bucle.

Comando continue

El comando continue nos va permitir saltar lineas de una iteración y pasar directamente a la siguiente.

Los comandos true y false

El comando true simplemente devuelve un 1, mientras que el comando false un 0. Mediante estos comandos es posible realizar bucles infinitos, en los cuales la única manera de salir es mediante el comando break o mediante la instrucción exit.

Tanto los condicionales como los bucles utilizan condiciones para determinar como actuar o cuando terminar, estas condiciones las tenemos que determinar nosotros. Para esta tarea es conveniente conocer los siguientes conceptos:

Comparación de cadenas alfanuméricas
 
Operador Verdad ( valor TRUE )  si
caena1=cadena2 cadena1 es igual a cadena2
cadena1!=cadena2 cadena es diferente a cadena2
cadena1<cadena2 cadena1 es menos que cadena2
cadena1>cadena2 cadena1 es mayor que cadena2
-n cadena1 cadena1 no es nula (longitud mayor que 0)
-z cadena1 cadena1 tiene un valor nulo (longitud 0)
Comparación de valores numéricos
Operador Verdad ( valor TRUE )  si
varx -lt vary varx menor que vary
varx -le vary varx menos o igual que vary
varx -eq vary varx igual que vary
varx -ge vary varx mayor o igual que vary
varx -gt vary varx mayor que vary
varx -ne vary varx diferente que vary

Comparación de atributos de fichero
Operador Verdad ( valor TRUE )  si
-d fichero Fichero existe y es un directorio
-e fichero Fichero existe
-f fichero Fichero existe y es un fichero regular (no un directorio, u otro tipo de fichero especial)
-r fichero Tienes permiso de lectura en fichero
-s fichero Fichero existe y no esta vació
-w fichero Tienes permiso de escritura en fichero
-x fichero Tienes permiso de ejecución en fichero (o de búsqueda si es un directorio)
-O fichero Eres el dueño del fichero
-G fichero El grupo del fichero es igual al tuyo
fichero1 -nt fichero2 Fichero1 es más reciente que fichero2
fichero1 -ot fichero2 Fichero1 es más antiguo que fichero2

Los condicionales

Los condicionales nos permiten realizar acciones solamente bajo las condiciones que nosotros indiquemos, de esta forma, podremos ejecutar un conjunto de instrucciones únicamente cuando se cumpla una condición determinada. Tenemos dos tipos de condicionales :

Condicional If-then-else

El condicional if es el más conocido y usado, su estructura es muy básica:

if [condición 1]
then
<comandos a ejecutar si se cumple la condición 1>
else
<comandos a ejecutar si no se cumple condición 1>
fi

Si se cumple la condición 1 se ejecutara el primer bloque de comandos, sino, el bloque después del “else”. Vamos a ver un ejemplo para que quede más claro:

cat if.sh
#! /bin/bash
var1=$1
var2=$2

if [ $var1 = $var2 ]; then
    echo "Son iguales"
else
    echo "Son diferentes"
fi

./if.sh hola hola
Son iguales
./if.sh hola adiós
Son diferentes

En este ejemplo estamos recibiendo dos parámetros de posición y los estamos comparando, indicando mediante la instrucción echo si ambos son iguales o diferentes.

Evaluación múltiple con case-esac

Es posible comprobar el valor de una variable de forma múltiple, la mejor forma de verlo es mediante un ejemplo:

cat case.sh

#! /bin/bash 
read a
  case $a in
     1)
        echo "uno"
     ;;
     2)
        echo "dos"
     ;;
     *)
        echo "ni idea de que numero es"
     ;;
esac

./cate.sh
5
ni idea de que numero es
./cate.sh
1
uno

El script anterior lee una variable desde la entrada estándar con el comando read y dependiendo su valor realiza un echo u otro. En este caso si el valor que se lee con el read es 1 o 2, lo indica mediante echo, por lo contrario,  indica: ni idea de que numero es.

Los bucles

Los bucles nos permiten repetir un conjunto de instrucciones todas las veces que necesitemos, estas se repetirán hasta que la condición indicada en el bucle se cumpla. Es importante tener cuidado y controlar que la condición del bucle se vaya a cumplir en algún momento, sino caeremos en un bucle infinito y tendremos que interrumpir la ejecución del script. En bash tenemos los siguientes bucles:

 Bucle For

Los bucles for en los shell scripts se basan en una o varias listas de elementos, que se asignan a una variable sucesivamente.

Su sintaxis es la siguiente:

for var in lista
do
<comandos a ejecutar>
done

Los valores de lista se van sustituyendo en var hasta que ya no queda nada. Vamos a ver algun ejemplo para comprender mejor el funcionamiento de este bucle:

Si no especificamos nada

cat for.sh

#! /bin/bash
for var
do
echo "$var"
done

./for.sh uno dos tres
uno
dos
tres

En el caso de no especificar ninguna lista al for, este utiliza los parámetros posicionales para el bucle, recorriendo cada uno de ellos y en este caso realizando un echo para cada uno.

Con una lista explicita

cat for.sh

#! /bin/bash
for var in fich1 fich2
do
    mkdir $var
done

Este script nos crea dos ficheros con el comando mkdir llamados fich1 y fich2.

Es posible realizar este bucle con otros elementos, como criterios de búsqueda, con un contador, etc.

Bucle while

Con el bucle while creamos una iteración condicional, de forma que, ejecutaremos una secuencia de comandos continuamente mientras se cumpla la condición. La estructura es la siguiente:

while condición
do
<comandos a ejecutar>
done

Veamos un Ejemplo:

cat while.sh

#!/bin/bash 
var1=30
echo "Introduzca un numero, a ver si aciertas:"
while true;
do
     read var2
     if [ $var1 = $var2 ]; then
         echo "Numero Correcto"
     break
     else 
     echo "Numero incorrecto, vuelve a intentarlo :"
     fi
done

./while.sh
4
Numero incorrecto, vuelve a intentarlo:
30
Numero Correcto

En este ejemplo hemos realizado un bucle infinito mediante la instrucción true, que solo terminara cuando introduzcamos el numero correcto (30).

Bucle until

El bucle until nos permite realizar un bucle condicional hasta que se cumpla una condición, en el momento que se cumpla esta condición se sale del bucle. Su funcionamiento es prácticamente el mismo al del while, su estructura es la siguiente:

until condicion
do
<comandos a ejecutar>
done

Vamos a ver un sencillo ejemplo en el que vamos a recorrer un contador desde 5 hasta 1, indicando en cada iteración, en la vuelta que nos encontramos.

cat until.sh

#!/bin/bash 
cont=5
until [ $cont -lt 1 ];
do
     echo Vuelta numero : $cont
     let cont=cont-1 
done

./while.sh
Vuelta numero : 5
Vuelta numero : 4
Vuelta numero : 3
Vuelta numero : 2
Vuelta numero : 1
Bucle select

El bucle select nos va permitir crear menús, con selección por numero. La inserción se efectúa mediante el teclado, y si el valor que damos no esta en el rango valido, el menú se imprime de nuevo, hasta que insertemos un valor correcto.

Su estructura es la siguiente:

select variable in lista_contenido
do
<comandos a ejecutar>
done

Un ejemplo:

#!/bin/bash
select eleccion in op1 op2 op3
  do
  if [ $eleccion ]; 
  then
      echo "Opcion elegida: $eleccion"
      break
  else
      echo "Elección incorrecta"
  fi
done

En este ejemplo tenemos 3 opciones, la elección que hagamos influirá en el valor de la variable eleccion, además una vez elegido un valor correcto entre 1-3 entraremos en la secuencia de instrucciones then con su respectivo break. Mientras no insertemos un valor entre 1-3 entraremos por el else y el bucle continuara.

Con esto damos por concluido el artículo, espero que os ayude en la construcción de vuestros shell scripts. Para mas información sobre los shell scripts en Linux, aquí están los artículos sobre el tema que hemos escrito hasta la fecha:

 

Sobre el autor / 

AsierPH

Entusiasta de las tecnologías libres y fundador de OvToaster.com | “Las obras de conocimiento deben ser libres, no hay excusas para que no sea así“

Articulos relacionados

14 comentarios

  1. Miguel Ángel 27 abril, 2016 at 6:50 pm -  Responder

    Muy bueno me estas salvando la vida mil gracias

    • AsierPH 29 abril, 2016 at 11:48 am -  Responder

      Con que te ayude un poco me conformo, gracias por comentar!

    • AsierPH 4 agosto, 2016 at 9:46 am -  Responder

      De nada Miguel Ángel 😀

  2. victor 28 noviembre, 2015 at 9:16 am -  Responder

    0 = true , 1 = false

    En serio?

    • AsierPH 28 noviembre, 2015 at 2:19 pm -  Responder

      Gracias por la corrección.
      Saludos

      • david 11 febrero, 2016 at 2:18 am -  Responder

        Creo que no estabas equivocado, estaba haciendo mis demos y en una condicional le puse para que evalúe una función, pero se me hizo raro que no entrara teniendo en cuenta lo que pusiste que true = 1, lo que hice fue ejecutar el true y false como funciones e imprimir sus valores

        #!/bin/bash
        true
        echo “true $?”
        false
        echo “false $?”

        y bueno me retorno lo siguiente:

        true 0
        false 1

        Al parecer true y false son funciones y no valores en sí (tal vez no).

  3. Jose 26 febrero, 2015 at 4:11 am -  Responder

    Excelente muy bien explicado. Una consulta lo sacas de algun libro en particular o es mero conocimiento? y piensas continuar ampliando las enseñanzas de scripting?

    • AsierPH 26 febrero, 2015 at 11:49 am -  Responder

      Muchas gracias por el comentario Jose,
      Los artículos sobre scripting los escribo sobre mi conocimiento, suelo soltar todo de golpe y lo voy estructurando, y si necesito revisar algo, suele ser muy puntual y lo busco en Internet.
      Y totalmente si, tengo pensado escribir mas artículos sobre scripting, de hecho tenia la idea de “organizar” una seria de artículos para completar un curso completo.
      ¡Un saludo!

  4. Adrian 7 junio, 2014 at 7:53 pm -  Responder

    Hola! muy útil la web! Estoy realizando un script en bash sobre el algoritmo óptimo, estoy trabajando con arrays tal como explicabas en otro post. Mi duda es:

    En el algoritmo óptimo yo lo que tengo que hacer es sustituir la página actual por la página que tiene que esperar mayor tiempo para ser referenciada. Por ejemplo, hay que tener en cuenta que trabajo con tres marcos:

    Array={7,0,1,2,3,1,7}
    Entran al frame 7,0,1 (trabajo con tres marcos) entonces la siguiente página a sustituir sería el número 7, dado que es la última en la lista, osea la que más tiempo espera para ser referenciada.

    Lo que no sé es como acceder, y saber que ese es el número que tengo que sustituir y que está en esa posición.

    Se te ocurriría algo?

    Mil gracias!! Espero su respuesta!!!!

    • AsierPH 25 junio, 2014 at 8:17 pm -  Responder

      Buenas Adrian, siento tanto en tardar en responder. Es época de exámenes y se me han acumulado las cosas,no consigo sacar el tiempo que me gustaría para ovtoaster.
      Respecto a tu duda, me seria de mucha utilidad que me facilitaras el código o aun que sea la parte en cuestión.
      Gracias por comentar Adrian y me alegro de que te sea útil el articulo.
      Saludos 😉

  5. Josep 7 mayo, 2014 at 9:23 am -  Responder

    Sólo una pequeña corrección, en el ejemplo para until has puesto while, con lo cual nunca se ejecutaría el bucle.

    Por lo demás todo correcto.

    • AsierPH 7 mayo, 2014 at 10:18 am -  Responder

      Buenas Josep,
      Gracias por la corrección, andar con tantos ejemplos al final me he liado xD, ya esta el until en el ejemplo del bucle until 🙂
      Un saludo!

  6. rhoconlinux 6 mayo, 2014 at 6:46 pm -  Responder

    excelente y muy útil!!!, felicitaciones y muchas gracias 😉

    • AsierPH 6 mayo, 2014 at 7:13 pm -  Responder

      Me alegro de que te guste rhoconlinux, ¡ Muchas gracias !

Deja tu comentario

Tu correo no sera publicado. Los campos requeridos están marcados *