Tutoriales sobre Bash Scripting III : Condicionales: if, elif, else, && y ||

En este capítulo hablaremos sobre los condicionales que tan importantes son a la hora de controlar el flujo de trabajo de nuestros scripts.

La sintaxis utilizando algo de pseudocódigo sería:

if condición
then
        echo "Me muestro si la condición es verdadera"
elif condición
then
        echo "Me muestro si la condición del primer if es falsa y la del elif es verdadera"
else
        echo "Me muestro si todas las condiciones anteriores son falsas"
fi

if condición; then echo "Me muestro si la condición es verdadera"; elif condición; then echo "Me muestro si la condición del primer if es falsa y la del elif es verdadera"; else; echo "Me muestro si todas las condiciones anteriores son falsas"; fi
condición && echo "Me muestro si la condición es verdadera"
condición || echo "Me muestro si la condición es falsa"
condición && echo "Me muestro si la condición es verdadera" || echo "Me muestro si la condición es falsa"

Como vemos la sintaxis es bastante sencilla y no muy distinta de la de otros lenguajes de programación o escripting.

Un detalle a tener en cuenta es que al then le ocurre lo mismo que al do de los loops, debe ir en la linea a continuación del if.

También se puede apreciar que el if se cierra con un fi al final de toda las instrucciones, no es necesario ponerlo antes de un else o un elif.

Veamos que es lo que substituiría a condición en el pseudocódigo anterior:

  • [ condición ]  : Este es el comando test tradicional de shell disponible en todas las shells POSIX. El comando test devuelve un exit code e if actúa en concordancia. Suele usarse para ver si un archivo/directorio existe o un número es igual a otro.
  • [[ condición ]] :Esta es una nueva variante soportada por bash, de nuevo el comando test devuelve un exit code con el cual if actúa. Entre sus opciones extendidas puede comparar si un string equivale a un expresión regular.
  • comando :Se ejecuta el comando e if actúa en función de su exit code.
  • ( comando ) :Este se ejecuta en una subshell. El comando devuelve un exit code e if actúa en base a él.  Usualmente se utiliza para limitar los efectos secundarios del comando en caso de que requiera asignación de variable u otros cambios en el entorno de la shell.
  • (( comando )) :Otra nueva variante soportada por bash utilizada para realizar operaciones ariméticas. Como resultado de la operación se genera un exit code e if actúa en consecuencia. Devuelve un exit code de 0 (True) en caso de que el resultado de la operación no sea cero.

La principal cosa que podemos ver con respecto a otras shell como sh son los modos [[ ]] y (( )), estos métodos no pertenecen a POSIX y pueden no funcionar en otras shells.

Otra diferencia con respecto a otros lenguajes de programación o escripting es la posibilidad de utilizar los exit codes de comandos para nuestras condiciones sin utilizar un if tal cual, seguramente habréis visto esto varias veces:

apt-get update && apt-get upgrade

Ahí donde lo veis eso es otro condicional:

  • && : Comprueba que el exit code sea cero.
  • || :Comprueba que el exit code sea distinto de cero.

Esto se utiliza sobre todo para encandenar comando donde queremos asegurarnos que el siguiente se ejecuta solo si el anterior fue exitoso (exit code 0). En el ejemplo anterior esto significa que si apt-get update se ejecuta correctamente entonces ejecutaremos apt-get upgrade.

Esto lo podemos combinar con la lista anterior para conseguir resultados como estos:

[ -f file.txt ] && echo "El archivo existe" || echo "El archivo no existe"

En este caso utilizaremos un condicional para comprobar si el archivo file.txt existe y en cada caso se mostrará el mensaje correspondiente.

Existen gran número de expresiones condicionales en bash, a continuación os dejo un listado:

  • -a archivo : True si el archivo existe.
  • -b archivo : True si el archivo existe y es un archivo de bloques.
  • -c archivo : True si el archivo existe y es un archivo de caracteres especiales.
  • -d archivo : True si el archivo existe y es un directorio.
  • -f archivo : True si el archivo existe y es un archivo regular.
  • -e archivo : True si el archivo existe.
  • -g archivo : True si el archivo existe y el bit set-group-id está marcado.
  • -h archivo : True si el archivo existe y es un enlace simbólico.
  • -k archivo : True si el archivo existe y el bit “sticky” esta marcado.
  • -p archivo : True si es un pipe tipo FIFO.
  • -r archivo: True si el archivo existe y se puede leer.
  • -s archivo : True si el archivo existe y su tamaño es mayor de cero.
  • -t fd : True si el file descriptor fd esta abierto y referencia a una terminal.
  • -u archivo : True si el archivo existe y el bit set-user-id esta marcado.
  • -w archivo : True si el archivo existe y se puede escribir.
  • -x archivo : True si el archivo existe y es ejecutable.
  • -G archivo : True si el archivo existe y pertenece al id de grupo en uso.
  • -L archivo : True si el archivo existe y es un enlace simbólico.
  • -N archivo : True si el archivo existe y fue modificado desde la última vez que fue leído.
  • -O archivo : True si el archivo existe y pertenece al usuario en uso.
  • -S archivo : True si el archivo existe y es un socket.
  • archivo1 -ef archivo2 : True si archivo1 y archivo2 hacen referencia al mismo dispositivo e inode.
  • archivo1 -nt archivo2 : True si archivo1 es más nuevo que archivo2 o si archivo1 existe pero archivo2 no.
  • archivo1 -ot archivo2 : True si archivo1 es mas viejo que archivo2 o si archivo2 existe pero archivo1 no.
  • -o nombreopt : True si la opción de shell nombreopt esta activada.
  • -v variable : True si la variable de shell  existe.
  • -R variable : True si la variable existe y es una referencia por nombre.
  • -z string : True si la longitud de string es cero.
  • -n string: True si la longitud de string es distinta de cero.

Cortita ¿verdad? ¡Pero si aun nos faltan las opciones para los strings y aritmética!

Comencemos con los strings:

  • string1 == string2  y string1 = string2 : True si los strings son iguales. El = se debe usar con el comando test conforme a POSIX.
  • string1 != string2 : True si los strings no son iguales.
  • string1 < string2 : True si la longitud de string1 es menor a string2.
  • string1 > string2 : True si la longitud de string1 es mayor a string2.

Y por último los operadores aritméticos binarios, que siguen la sintaxis arg1 OP arg2, donde los args pueden ser enteros positivos o negativos y OP es uno de los siguientes:

  • -eq : Igual.
  • -ne : No igual.
  • -lt : Menor que.
  • -le : Menor o igual que.
  • -gt : Mayor que.
  • -ge : Mayor o igual que.

Puede parecer que son muchísimas opciones para acordarse de todas pero como con todo o acostumbraréis a utilizar las más comunes muy rápidamente.

Espero os haya gustado este nuevo post de la serie sobre bash scripting y cualquier duda o comentario no dudéis en dejar un comentario.

Como siempre, gracias por vuestra visita, saludos!

Esta entrada fue publicada en bash, tutorial. Guarda el enlace permanente.

Una respuesta a Tutoriales sobre Bash Scripting III : Condicionales: if, elif, else, && y ||

  1. prueba dijo:

    Hola una pregunta y perdona por escribir esto siendo que no tiene nada que ver aquí podrías hacer un tutorial sobre Pibunny o P4wnP1 si es posible

Deja un comentario