OPERADORES Y ESTRUCTURAS CONDICIONALES

Como en todos los lenguajes de programación, los scripts de Bash también cuentan con estructuras condicionales para tomar decisiones. Las condiciones pueden ser:

Condición Significado
a -lt b (-less than) Un número entero es menor que otro: a < b
a -le b (-less or equal to) Un número entero es menor o igual a otro: a <= b
a -gt b (-greater than) Un número entero es mayor que otro: a > b
a -ge b (-greater or equal to) Un número entero es mayor o igual a otro: a >= b
a -eq b (-equal to) Un número entero es igual a otro: a == b
a -ne b (-not equal to) Un número entero NO es igual a otro: a != b
exp1 && exp2
exp1 -a exp2
(AND) Si y sólo si ambas expresiones son verdaderas
exp1 || exp2
exp1 -o exp2
(OR) Si al menos una expresión es verdadera
! cond (NOT) Si la condición NO se cumple (si es falsa)
-z str (-zero) Si str es una cadena de texto vacía
-n str (-number) Si str NO es una cadena de texto vacía
str1 == str2 Si str1 es igual a str2
str1 != str2 Si str1 NO es igual a str2
str1 < str2 Evalúa si str1 es alfabéticamente menor que str2
str1 > str2 Evalúa si str1 es alfabéticamente mayor que str2
-e arch (-exists) Si un archivo o directorio existe
-s arch Si un archivo o directorio existe y no está vacío
-d arch (-directory) Si es un directorio
-f arch (-file) Si es un archivo
-L arch (-Link) Si es un enlace simbólico (un acceso directo)
-r arch Si tiene permiso de lectura
-w arch Si tiene permiso de escritura
-x arch Si tiene permiso de ejecución

Operadores de igualdad

Cabe hacer un par de aclaraciones sobre los operadores de igualdad y desigualdad. En primer lugar, los operadores == y -eq no son lo mismo: el primero es para comparar texto y el segundo es para comparar números enteros. De manera análoga, != es para comparar la desigualdad entre cadenas de texto y -ne para enteros.

Condicional if-else

La sintaxis más simple con if es:

if [ condición ]; then
    # código
fi

O lo que es lo mismo:

if [[ condición ]]
then
    # código
fi

Verás que varias veces se emplean corchetes simples ([ ]) o dobles ([[ ]]) indistintamente, pero en realidad no es lo mismo: los simples se usan cuando se trata de números y los dobles cuando se trata de strings:

if [ 14 -le 75 ]
if [[ "barril" < "carro" ]]

Es recomendable utilizar siempre corchetes dobles para evitar errores. Lo que sí es importante es dejar espacios entre los corchetes y la expresión condicional.

Luego de la condión se escribe ; then (o bien then en la línea siguiente) y a continuación el código de cuando se cumple la condición. Finalmente, la expresión fi (if al revés) es la que cierra el bloque.

NOTA: En Bash (como en Python) son muy importantes las indentaciones, no solamente por una cuestión de legibilidad.

La estructura con un único else es la siguiente:

if [[ condición ]]; then
    # código
else
    # código
fi

Como podrás apreciar, else no lleva ; then porque es la única alternativa en este caso.

Por supuesto que también se pueden anidar estructuras, cerrando cada bloque if con su respectivo fi:

if [[ condición_1 ]]; then
    if [[ condición_1_1 ]]; then
        # código
    fi
...
fi

Y si una estructura compleja requiere varios else encadenados, éstos se convierten en elif (else-if), salvo el último:

if [[ condición_1 ]]; then
    # código
elif [[ condición_2 ]]
    # código
# ...
else
    # código
fi
NOTA: Se pueden tener tantos elif como sean necesarios, pero en la medida en que se cumpla la primera condición, los restantes no se evaluarán.

Pongamos por ejemplo un programa que le pida al usuario ingresar una temperatura en grados Celsius:

#!/bin/bash

echo "Ingresa una temperatura en ºC: "
read temp

if [[ $temp -gt 10 ]]; then
    if [[ $temp -lt 15 ]]; then
        echo "Está fresco."
    elif [[ $temp -le 25 ]]; then
        echo "El clima está agradable."
    else
        echo "Hace calor."
    fi
else
    echo "Hace mucho frío."
fi

Si la sentencia es simple, se puede escribir en una única línea, finalizando el correspondiente a cada bloque con punto y coma (;):

if [[ condición ]]; then código_if; else código_else; fi

Ejercicios

  1. Crear un ejecutable que acepte un número entero como argumento e indique por consola:
    1. Si es mayor que 100
    2. Si es menor o igual a 100 y mayor que 50
    3. Si es menor o igual a 50 y mayor que 10
    4. Si es menor o igual a 10 y mayor o igual a 0, y además:
      1. Si es mayor o igual a 0 y menor que 5
      2. Si es mayor o igual a 5 y menor o igual a 10
    5. Si es negativo
  2. Ejecutarlo con distintos valores para cada caso.
  3. Evaluar estos strings:
    • Si "algebraico" es menor que "algoritmo"
    • Si "archivo" es mayor que "Archivo"
    • Si "Zapallo" es mayor que "albahaca"

Condicional case

El condicional case es análogo al switch en otros lenguajes de programación y su sintaxis es similar:

case variable in
    valor_1 )
        código_1;;
    valor_2 )
        código_2;;
    * )
        código_por_defecto;;
esac

También puedes escribir una opción por línea:

case variable in
    valor_1) código_1...;;
    valor_2) código_2...;;
    ...
    *) código_por_defecto...;;
esac

Como se puede apreciar, cada valor que puede adoptar la variable va seguida de ) y el código de cada bloque se cierra con doble punto y coma (;;). Al final de todas las opciones se debe definir una por defecto que está indicada con *, y por último la estructura se cierra con esac (case al revés).

Por ejemplo, pedirle al usuario que ingrese un caracter:

#!/bin/bash

echo "Ingresa un caracter: "
read char

case $char in
    [a-z] )
        echo "Has ingresado una letra minúscula";;
    [A-Z] )
        echo "Has ingresado una letra mayúscula";;
    [0-9] )
        echo "Has ingresado una cifra";;
    * )
        echo "Has ingresado un caracter especial";;
esac

Ejercicios

  1. Escribir un programa que le pida al usuario elegir una opción de un menú de 5 comidas distintas.
  2. Escribir otro programa donde el usuario ingrese su nombre e indicar si su inicial está entre la A y la I, o entre la J y la Q, o entre la R y la Z.