If-else en Bash

En Bash podemos controlar qué partes de nuestro script se ejecutan usando un if. El formato del if es el siguiente:

if [ condición ]; then
        echo "Esto se muestra si se cumple la condición"
fi

o también:

if [ condición  ]
then
        echo "Esto se muestra si se cumple la condición"
fi

Busca la diferencia entre ambas formas. Tienes media hora... y el tiempo empieza a contar ¡ya!

Si pones el then en la misma línea del if debes usar un ';' para evitar errores. Puedes usar la forma que prefieras.

Condición

En la condición podemos usar comparaciones entre valores, expresiones complejas o el valor de salida de un programa.

Ejemplo 1: Comprobar si existe un fichero

#!/bin/bash

touch fichero_prueba # touch crea un fichero en blanco

if [ -f fichero_prueba ];
then
        echo "El fichero existe"
fi

Este script comprueba si existe el fichero fichero_prueba. He hecho trampa y he usado touch para asegurarme de que el fichero existe (touch es un comando que crea un fichero en blanco si no existe).

La comprobación se hace a través de: -f fichero_prueba.

Existen un montón de opciones similares a ésta, por ejemplo:

  • -d : comprueba si existe un directorio.
  • -x : comprueba si existe el fichero y si es ejecutable.
  • -w : comprueba si existe el fichero y si tu script puede modificarlo (si tiene permisos de escritura).

Hay otro montón de opciones. Si saco tiempo intentaré hacer una recopilación.

Ejemplo 2: Comparar cadenas de texto

Podemos ver si dos cadenas de texto son iguales usando el operador '==':

#!/bin/bash

texto1="Hola"

if [ "$texto1" == 'Hola' ];
then
        echo "Son iguales"
fi

Hay otras opciones como:

  • != Comprueba si las cadenas son diferentes.
  • > Comprueba si la cadena de la izquierda es mayor que la derecha.
  • < ¿imaginas lo que hace?
También podemos comprobar si la cadena tiene una longitud mayor que cero (vamos, que tiene algún carácter) usando el operador -n:
#!/bin/bash

texto1="Hola"

if [ -n "$texto1" ];
then
        echo "La cadena no está vacía"
fi

O podemos comprobar si una cadena está vacía usando -z:

#!/bin/bash

texto1=""

if [ -z "$texto1" ];
then
        echo "La cadena está vacía"
fi

Ejemplo 3: Comparar números

También podemos comparar números, pero no podemos usar los operadores <, >, ==. Lo sé, es un incordio, pero es así.

Para ver si dos números son iguales usamos -eq (de equal en inglés):

#!/bin/bash

numero=4

if [ "$numero" -eq 4 ];
then
        echo "El número es 4"
fi

Hay otras opciones:

  • -ne (not equal): Es verdadero si los números son diferentes.
  • -gt (greater than): Es verdadero si el valor de la izquierda es mayor que el de la derecha.
  • -ge (greater than or equal): Es verdadero si el de la izquierda es mayor o igual que el de la derecha.
  • -lt (less than): Verdadero si el de la izquierda es menor.
  • -le (less than or equal): Verdadero si el de la izquierda es menor o igual que el de la derecha.

Ejemplo 4: Negación

Si a una condición verdadera le ponemos el símbolo '!' delante se convierte en falsa. Si hacemos lo mismo con cuna condición falsa se convierte en verdadera. Por ejemplo:

if [ ! "1" == "1" ]

será falsa.

Ejemplo 5: Resultado de un programa

Se puede usar como condición el resultado de un programa. Aquí hay una cosa curiosa. Si conoces algún otro lenguaje de programación el cero suele significar que la condición es falsa. En bash el cero se toma como verdadero y un valor distinto de cero como falso.

¿Por qué es así? ¿Acaso los creadores de Bash son unos locos contra el mundo? Tenían una buena razón para hacerlo así; cuando un programa funciona con normalidad, al terminar, devuelve un 0 al que lo ha llamado. Si ha habido algún error devuelve un valor mayor que cero.

Vamos a comprobar el resultado de un programa con este ejemplo:

#!/bin/bash

touch /root/prueba

if [ $? -eq 0 ];
then
        echo "Se ha creado el fichero"
fi

Aquí el comando touch intentará crear el fichero /root/prueba y fallará... porque no estás logueado como usuario root ¿no?

Al fallar mostrará un mensaje de error pero ¿cómo se entera nuestro script de que el programa ha fallado? Pues a través de la variable $?

$? es una variable especial que recoge el valor devuelto por el último programa ejecutado. Cuando touch funciona sin problemas devuelve el valor 0; cuando falla, como en este caso, devuelve un número distinto de cero.

Entonces bastará con comprobar si la variable $? tiene almacenado un 0 para ver si ha funcionado correctamente.

Este otro script debería funcionar sin problemas porque touch va a devolver un cero:

#!/bin/bash

touch prueba

if [ $? -eq 0 ];
then
        echo "Se ha creado el fichero"
fi

If else

También podemos ejecutar un bloque de código si la condición no se cumple con un if-else:

#!/bin/bash

if [ "$1" == "Hola" ];
then
        echo "Que tal?"
else
        echo "No se qué decirte"
fi

En este ejemplo he usado la variable $1 que, si recuerdas del artículo anterior, recoge el primer parámetro que se ha puesto al llamar al script. Por ejemplo, si llamamos al script ejemploif:

$ ./ejemploif Hola
Que tal?
$ ./ejemploif Adiós
No se qué decirte

Nota: ten en cuenta que no es lo mismo contestar “Hola” que “hola”. Haz la prueba.

If elif else

También podemos usar el elif que nos permite comprobar si se cumplen varias condiciones. Si no se cumple la del if se comprueba la del elif, si ésta tampoco cumple se ejecuta el bloque del else:

#!/bin/bash

if [ "$1" == "Hola" ];
then
        echo "Que tal?"
elif [ "$1" == "Adiós" ];
        echo "Hasta pronto"
else
        echo "No se qué decirte"
fi

En este ejemplo si el usuario dice “Hola” el script le contesta “Qué tal”. Si no, si el usuario escribe “Adiós” le contesta “Hasta pronto”. Si escribe cualquier otra cosa le contesta “No sé qué decirte”.

Podemos añadir todos los elif que queramos.

If anidados

También podemos meter un if dentro de otro:

if [ condicion1 ]; then
        if [ condicion2 ]; then
                ...
        fi
fi

Recomendaciones

Espacios entre la condición y los corchetes

Los corchetes deben ir separados de la condición por espacios. Igual que el operador que uses. Prueba a quitar los espacios en este script para ver los distintos errores:

#!/bin/bash

if [ "$1" =="Hola" ]; then
        echo "Que tal?"
fi

Las variables entre comillas

Habrás visto que en las condiciones, siempre que pongo una variable la pongo entre comillas. Es muy, muy recomendable poner siempre las variables entrecomilladas. ¿La razón? Prueba con este ejemplo:

#!/bin/bash

if [ $1 == "Hola" ]; then
        echo "Que tal?"
fi

Es lo mismo que hemos estado haciendo hasta ahora pero la variable $1 no va entre comillas.

Ahora ejecútalo usando:

$ ./ejemploif Hola

Todo bien ¿no?

Ahora prueba con:

$ ./ejemploif "Hola amigo"
./if-else: line 3: [: too many arguments

¡Ups! (nada que ver con la multinacional del transporte) un error. Eso es porque Bash convierte la condición en:

if [ Hola amigo == "Hola" ]; then

Si hubiéramos tenido las comillas habría hecho:

if [ "Hola amigo" == "Hola" ]; then

y no habríamos tenido ningún problema.

También tendríamos problemas si el usuario llama al script sin parámetros:

$ ./ejemploif

Porque el if se convertiría en:

if [ == "Hola" ]; then

Y se nos queda cojo.

Por estas razones es recomendable usar las comillas para las variables.

Dobles corchetes

Me dejo algunas cosas en el tintero como los dobles corchetes y los AND y OR pero de eso escribiré en otra entrega, que este post me está quedando demasiado largo.

Autor:
Nivel: Principiante
Palabras clave:
Fecha publicado:
Fecha actualizado: 15-08-2016

Otros capítulos de la misma serie

Este capítulo es parte de la serie: Programación en BASH.

Y muchos más en preparación.

Disponible en los planes: Laravel hero PHP a tope