Cómo dominar las sentencias If…Else de Bash con [[ ]], Elif y operadores lógicos

A veces, los scripts de Bash pueden ser un verdadero problema cuando los condicionales fallan o se comportan de forma inesperada. No siempre se trata de errores de sintaxis; a menudo, se trata de pequeños problemas como olvidar las comillas, confundir operadores o usar la sintaxis de prueba incorrecta. Estos pequeños errores pueden provocar que los scripts ejecuten la rama incorrecta, omitan comprobaciones cruciales o simplemente fallen sin una pista clara. Es un poco extraño, pero una vez que se conocen los problemas comunes, escribir condicionales fiables se vuelve mucho más fácil. Además, en algunas configuraciones, los scripts que fallan la primera vez pueden funcionar después de reiniciar el sistema o la consola; Windows y Linux no siempre funcionan bien con estos problemas.

Esta guía detalla varias maneras probadas de escribir condicionales de Bash menos complejos. Aprenderá a usar sintaxis moderna como [[ ]], realizar operaciones aritméticas con (( ))para una matemática más clara, mantener la portabilidad con POSIX [ ]e incluso consolidar la lógica con case. Si lo hace correctamente, sus scripts se ejecutarán fluidamente, sin sorpresas. Mejor aún, le ayudará a evitar esos momentos de confusión en los que no está seguro de si el problema es su código o simplemente problemas de la shell.

Cómo solucionar los condicionales de Bash que no funcionan correctamente

Método 1: Escribir if...elsecon Bash[[ ]]

La [[ ]]sintaxis es una especie de versión mejorada de la antigua [ ]. Es más flexible, evita la división accidental de palabras, los problemas con comodines y, en general, se comporta de forma más predecible. Es imprescindible para los scripts de bash modernos, especialmente si quieres evitar errores extraños.

He aquí un ejemplo rápido:

#!/usr/bin/env bash set -euo pipefail read -r -p "Enter a value: " val if [[ "$val" == "admin" ]]; then echo "Welcome, admin." else echo "Access limited." fi 

Observa cómo se usa ==para la coincidencia de cadenas. Siempre comillas tus variables, incluso si son de una sola palabra, para evitar problemas con espacios o cadenas vacías. Es un pequeño hábito, pero te ahorra muchos dolores de cabeza.

Comparar cadenas y números de forma segura

user="alice" target="alice" if [[ "$user" == "$target" ]]; then echo "Usernames match." else echo "Usernames differ." fi # Numeric comparison: read -r -p "Enter a number: " n if [[ "$n" -gt 10 ]]; then echo "Greater than 10." elif [[ "$n" -eq 10 ]]; then echo "Equal to 10." else echo "Less than 10." fi 

Asegúrese de citar las variables en estas pruebas para que las cadenas vacías o los espacios no interfieran. Las comparaciones numéricas usan -gt, -eq, etc., al igual que en los scripts de shell clásicos.

Existencia y permisos de archivos

path="./data.txt" if [[ -f "$path" ]]; then echo "File exists." else echo "Creating file..." : > "$path" # creates an empty file fi 

Esto ayuda a comprobar si un archivo está presente y, de no ser así, crea uno. Resulta útil para scripts que inicializan configuraciones o procesan archivos.

Combine múltiples condiciones con &&y||

file="./report.log" size=5 if [[ -f "$file" ]] && [[ "$size" -ge 5 ]]; then echo "Process report." fi role="staff" if [[ "$role" == "admin" || "$role" == "staff" ]]; then echo "Privileged access granted." fi 

Esta sintaxis ordenada evita errores que ocurren cuando usted agrega accidentalmente demasiados corchetes u olvida espacios (el shell es muy exigente con eso).

Úselo elifpara múltiples comprobaciones

status="warning" if [[ "$status" == "error" ]]; then echo "Exit immediately." exit 1 elif [[ "$status" == "warning" ]]; then echo "Log and continue." else echo "All good." fi 

Esto es mucho más limpio que escribir un montón de ifs anidados. Ayuda a mantener la legibilidad del script y a reducir la probabilidad de errores.

Método 2: Haz matemáticas con(( ))

Si tu script solo procesa números enteros, (( ))es una forma mucho más ordenada de gestionar comparaciones y cálculos. Es más limpio y rápido, y además, se asemeja más a las matemáticas tradicionales.

Ejemplo de comparaciones matemáticas:

a=12 b=8 if (( a > b )); then echo "a is larger." elif (( a == b )); then echo "Equal." else echo "b is larger." fi 

Cuando tenga varias condiciones numéricas, simplemente encadene con &&o ||dentro de (( )). Funciona mucho mejor que combinar pruebas:

x=7 y=3 z=10 if (( (x > y) && (z >= 10) )); then echo "Threshold met." fi 

Nota: para validar la entrada, verifique siempre si lo que lee es en realidad un número, especialmente si hay una entrada del usuario involucrada — [[ "$n" =~ ^-?[0-9]+$ ]].

Método 3: Mantenlo portátil con POSIX[ ]

Si su script necesita ejecutarse en shells POSIX estrictos o incluso en /bin/sh, use [ ]. Es más antiguo, pero sigue siendo fiable.

#!/bin/sh a="hello" b="hello" if [ "$a" = "$b" ]; then echo "Match." else echo "No match." fi # Numeric comparison: a=5 b=30 if [ "$a" -lt "$b" ]; then echo "a is less than b." fi # String lex order: x="apple" y="banana" if [ "$x" \< "$y" ]; then echo "apple comes before banana." fi 

Asegúrese de escapar los signos “menor que” al realizar comparaciones de cadenas en shells POSIX, ya que de lo contrario el shell podría confundirse. Es extraño, pero así es como lo gestiona POSIX.

Método 4: Simplificar con casedeclaraciones

Cuando una sola variable puede tener múltiples valores, casees una forma más limpia de manejar la ramificación que un montón de ifs.

read -r -p "Enter mode (start|stop|status): " mode case "$mode" in start) echo "Starting...";; stop) echo "Stopping...";; status) echo "Service is running.";; *) echo "Unknown mode."; exit 1;; esac 

Y para múltiples partidos:

level="warn" case "$level" in error|err) echo "Exit with failure."; exit 1;; warn|warning) echo "Log warning.";; info|debug) echo "Proceed normally.";; *) echo "Unrecognized level.";; esac 

Método 5: Depuración y mejores prácticas

  • Agrupe las condiciones complejas entre paréntesis para mayor claridad. No es obligatorio, pero ayuda a mantener la coherencia.
  • Úselo ==para cadenas, -eqpara números enteros y siempre entre comillas las variables.
  • Activa la depuración set -xcuando algo no funcione: comenzará a mostrar cada comando a medida que se ejecuta, para que puedas detectar dónde está fallando.
set -x # turn on tracing # your conditions here set +x # turn it off when done 
  • Mantenga la sangría consistente, incluso si al shell no le importa: esto hace que sea más fácil leer y corregir errores más adelante.

Hoja de trucos rápida para operadores

  • Cadenas: ==, !=, -n var(no vacías), -z var(vacías)
  • Números: -eq, -ne, -gt, -lt, o use (( ))sintaxis.
  • Archivos: -f(existe y archivo normal), -d(directorio), -e(existe), -x(ejecutable), etc.
  • Lógica: &&(y), ||(o), !(no)

Resumen

Básicamente, la mayoría de los problemas con las condiciones de Bash se deben al uso de una sintaxis de prueba incorrecta, operadores erróneos o comillas omitidas.Úsalo [[ ]]para la mayoría de las tareas, (( ))para matemáticas y [ ]si necesitas la máxima compatibilidad. Añade un poco de depuración y validación de entrada, y tus scripts serán mucho más predecibles. Solo es cuestión de desarrollar buenos hábitos y comprender el funcionamiento interno de cada prueba.

Resumen

  • Úselo [[ ]]para pruebas de cadenas y archivos: más seguro y más moderno.
  • Úselo (( ))para matemáticas: sintaxis más limpia para números enteros.
  • Siempre cite las variables para evitar sorpresas.
  • Úselo casepara múltiples ramas basadas en una sola variable.
  • Recuerde activar la depuración si las cosas salen mal ( set -x).

Con suerte, esto le ahorrará algunas horas a alguien que intenta depurar sus scripts de bash. Porque sí, usar scripts de shell puede ser complicado, pero una vez que aprendes a hacer estas pruebas correctamente, se vuelve mucho menos frustrante.