Condiciones en Bash
SOLUCIONARIO
Condiciones en Bash
2024-10-25
Por
Occam's Razor

Condicionales en Bash

#!/bin/sh

readonly N=42
read -p "Adivina en que número estoy pensando ? " V

[ $V -lt 0 ] && (echo "Solo números positivos"; exit 1)

#if [ $V -lt 0 ]
#then
#    echo "Solo números positivos"
#    exit 1
#fi


if [ $V -eq $N ]
then
    echo "Bien hecho!"
else
    echo "Sigue Probando!"
    echo "El numero es " $([ $V -lt $N ]  && echo "MAYOR" || echo "MENOR")
    # Si hemos fallado damos una pista
    H=$([ $((N-V)) -lt 0 ] && echo $((V-N)) || echo $((N-V)))

    echo -n "PISTA : "
    if [ $H -lt 5 ] ; then echo "TE QUEMAS!!!";
    elif [ $H -lt 10 ] ; then echo "CALIENTE";
    elif [ $H -lt 15 ] ; then echo "TEMPLADO";
    else echo "FRIO"
    fi
    
fi

Bash, como podéis comprobar es una bestia totalmente diferente al resto de lenguajes que hemos visto hasta ahora. Si bien, todos los elementos de los que hemos hablado hasta ahora se pueden identificar fácilmente, la sintaxis de cada uno de ellos es bastante diferente de lo que estamos acostumbrados.

Lo primero que podemos observar es que Bash utiliza la palabra clave then para identificar el bloque principal de la expresión. Nos ofrece también la opción else if utilizando la palabra clave elif así como else como condición final catch-all. Los bloques condicionales se terminan con fi que no es otra cosa que if al revés.

SOY NOVATO

Las variables en los scripts bash se pueden declarar en cualquier momento sin más. Estas variables son siempre cadenas de caracteres y la forma de acceder a su contenido es utilizando el caracter $ como prefijo.

Para utilizar los valores de las variables como números es necesario hacer uso de programas como [ o expr.

Las condiciones son un tanto peculiares para lo que estamos acostumbrados. La razón es que Bash maneja todas sus variables como cadenas de caracteres los operadores como -eq (igual del inglés equal) o -lt (menor que del inglés Less Than) le indican a Bash que debe tratar los parámetros como números.

Como podéis ver, esas condiciones hay que ponerlas siempre entre corchetes… Y mucho ojo con los espacios antes y después.

SABIAS QUE

Si, [ es un programa, lo puedes encontrar en /usr/bin. Esa es la razón por la que es necesario dejar un espacio entre [ y el primer parámetro… De la misma forma el caracter ] es utilizado para indicar el final de la condición que queremos evaluar y por esa misma razón necesita un espacio antes, no es más que otro parámetro que pasamos en la línea de comandos separado por espacios.

El Operador ternario en bash se puede simular con las operaciones && y ||. La primera es un AND lógico y la segunda un OR. Cuando conectamos dos comandos con &&, bash debe asegurarse de que ambos comandos se ejecutan (devuelven el valor 0). Así, si el primer comando falla el segundo ya no se ejecuta puesto que el resulta será falso (el primero ya ha fallado).

El OR funciona de forma similar, este nos asegura que al menos uno de los comandos se ejecuta, de forma que si el primero se ha ejecutado con éxito, no hay necesidad de ejecutar el segundo.

SOY NOVATO

Bash define una serie de variables internas como por ejemplo $?, la cual nos devuelve el valor retornado por el último programa ejecutado. Por ejemplo:

    $ ls /tmp
    (lista de ficheros en /tmp)
    $ echo $?
    0
    $ ls /a # Utiliza cualquier directorio que sepas que no existe
    ls: cannot access '/a': No such file or directory
    $ echo $?
    2

Estos son los valores usados por el programa [.

Usando estos dos operadores, podemos simular el operador ternario de otros lenguajes con expresiones como:

[ CONDICION ] && INSTRUCCION-THEN || INSTRUCCION-ELSE

Bash comienza ejecutando el primer programa [ que evalua la condición. Si la condición es cierta [ retorna 1 y como lo que sigue es un && ejecutará el siguiente comando, la INSTRUCCION-THEN. Como lo que sigue es un || y ya se ha cumplido la primera parte… Bash no necesita calcular la segunda parte del OR.

Si [ retorna 0 (la condición no se cumple), Bash se saltará la siguiente instrucción que está conectada con &&, ya que es imposible cumplir que ambas instrucciones se puedan ejecutar correctamente (la primera ya ha fallado). Así que continua evaluando y se encuentra el ‘||’, como la primera parte del ‘||’ es falsa, evalúa la segunda a ver si todavía puede cumplir la condición, efectivamente ejecutando INSTRUCCION-ELSE.

Ahí queda eso. Quizás te resulte más sencillo escribir un bloque if-then-else después de todo. Puedes escribir una condición sencilla en una sola línea de la siguiente forma:

if [ CONDICION ]; then INSTRUCCION-THEN; else INSTRUCCION-ELSE; fi

SABÍAS QUE?

El comando interno read nos permite leer datos del usuario en nuestro programa. Usando el flag -p podemos incluir un prompt (o un mensaje a mostrar al usuario) para darle información sobre que tipo de información esperamos. En bash todas las variables contienen cadenas de caracteres así que no es necesario ningún tipo de conversión.

Bash también nos ofrece una instrucción del tipo switch para anidar condiciones. En este caso, el formato es como el que sigue:

case $var in
  caso1)
    comandos
    ;;
  caso2)
    comandos
    ;;
  *)
    comandos-por-defecto
    ;;
esac

Los distintos casos de la instrucción case pueden ser cualquier tipo de cadena de caracteres, incluyendo expresiones regulares:

case $H in
  [1-5])
    echo "Cualquier valor entre 1 y 5"
    ;;
  8?)
    echo "Ochentaitantos";
    ;;
  Linux*)
    echo "Cualquier cosa que empiece for Linux"
    ;;
  "6" | "7")
    echo "Cuatro o 5"
    ;;
   *)
     echo "Todo lo demás"
     ;;
esac    

Para declarar constantes en nuestros scripts shell podemos utilizar el comando readonly, el cual mostrará un error y terminará nuestro script en caso de que modifiquemos una de esas variables. Esta es la solución usada en el programa de ejemplo al principio del texto.

bash permite declarar variables de solo lectura de la siguiente forma:

declare -r N=42
Para terminar, observad que en el programa hemos utilizado los paréntesis (...) para agrupar comandos. Usados sin más, ejecutará todos los comandos entre los paréntesis uno tras otro como un subproceso, pero si anteponemos el signo $ nos devolverá la salida de los programas como una cadena. Podéis ver ejemplos de el uso de ambos casos en el programa de ejemplo.

Resumen

  • Soporta if ... then ...[else] ... fi

  • Soporta una specie de operador terciario

    [ CONDICION ] && INSTRUCCION-THEN || INSTRUCCION-ELSE

  • No soporta booleanos: ==0 -> FALSO y !=0 VERDADERO

  • Soporta switch : case VAL in ; case REGEXP) code;; *) default;; esac

  • Constantes con comando readonly o declare -r (solo bash).

Interesado en aprender Bash

A través de nuestra cuenta del Programa de Afiliados de Amazon, te recomendamos este libro:

Learning the bash Shell .

Como parte de este programa, recibimos una comisión por compras realizadas utilizando este enlace.


SOBRE Occam's Razor
Somos una revista libre que intenta explicar de forma sencilla conceptos tecnológicos y científicos de los que no podemos escapar. Al final, todo es más fácil de lo que parece!

 
Tu publicidad aquí :)