Condicionales: if, else, elif

Aprende a tomar decisiones inteligentes en tus scripts de Bash

Módulo 3 ⏱️ 25-30 min 🔀 Control de Flujo ⚡ Condicionales 📚 Principiante

¿Qué son las Estructuras Condicionales?

Las estructuras condicionales permiten que tu script tome decisiones basadas en diferentes condiciones. Son la base de la programación lógica y te permiten crear scripts que reaccionen de manera diferente según las circunstancias.

En Bash, la estructura condicional principal es if, que puede combinarse con else y elif para crear lógica compleja.

Flujo de una Estructura Condicional
Condición

¿Es verdadera?

Sí ↓
No →

Ejecutar if
Ejecutar else

Estructura if Básica

La sintaxis básica de if en Bash sigue esta estructura:

Sintaxis básica de if Copiar
if [ condición ]; then
    # Comandos si la condición es verdadera
    comando1
    comando2
fi
Elementos Clave
  • if: Palabra clave que inicia la condición
  • [ condición ]: La condición a evaluar (espacios importantes)
  • then: Separa la condición de los comandos
  • fi: Termina la estructura condicional (if al revés)
# Ejemplo básico: verificar si un archivo existe
$ cat > verificar_archivo.sh << 'EOF'
#!/bin/bash
archivo="mi_archivo.txt"

if [ -f "$archivo" ]; then
    echo "El archivo $archivo existe"
    ls -la "$archivo"
fi
EOF

$ chmod +x verificar_archivo.sh

# Crear el archivo para probar
$ touch mi_archivo.txt
$ ./verificar_archivo.sh
El archivo mi_archivo.txt existe
-rw-r--r-- 1 user user 0 oct 15 11:30 mi_archivo.txt

if-else: Dos Caminos

Con else puedes definir qué hacer cuando la condición es falsa:

Sintaxis if-else Copiar
if [ condición ]; then
    # Si la condición es verdadera
    comandos_verdaderos
else
    # Si la condición es falsa
    comandos_falsos
fi
# Ejemplo: verificar edad para votar
$ cat > verificar_edad.sh << 'EOF'
#!/bin/bash
echo "¿Cuál es tu edad?"
read edad

if [ "$edad" -ge 18 ]; then
    echo "¡Puedes votar! Tienes $edad años."
    echo "Tu deber cívico te espera."
else
    echo "Aún no puedes votar. Te faltan $((18 - edad)) años."
    echo "¡Pero puedes prepararte para ser un ciudadano informado!"
fi
EOF

$ chmod +x verificar_edad.sh
$ ./verificar_edad.sh
¿Cuál es tu edad?
16
Aún no puedes votar. Te faltan 2 años.
¡Pero puedes prepararte para ser un ciudadano informado!

elif: Múltiples Condiciones

Cuando necesitas evaluar múltiples condiciones, usa elif (else if):

Sintaxis if-elif-else Copiar
if [ condición1 ]; then
    # Si condición1 es verdadera
    comandos1
elif [ condición2 ]; then
    # Si condición1 es falsa pero condición2 es verdadera
    comandos2
elif [ condición3 ]; then
    # Si condiciones anteriores son falsas pero condición3 es verdadera
    comandos3
else
    # Si todas las condiciones son falsas
    comandos_por_defecto
fi
# Ejemplo: clasificador de calificaciones
$ cat > calificaciones.sh << 'EOF'
#!/bin/bash
echo "Introduce tu calificación (0-100):"
read calificacion

if [ "$calificacion" -ge 90 ]; then
    echo "¡Excelente! Calificación: A ($calificacion)"
    echo "🎉 ¡Felicitaciones por tu dedicación!"
elif [ "$calificacion" -ge 80 ]; then
    echo "¡Muy bien! Calificación: B ($calificacion)"
    echo "👍 Buen trabajo, sigue así."
elif [ "$calificacion" -ge 70 ]; then
    echo "Bien. Calificación: C ($calificacion)"
    echo "📚 Con un poco más de esfuerzo puedes mejorar."
elif [ "$calificacion" -ge 60 ]; then
    echo "Suficiente. Calificación: D ($calificacion)"
    echo "⚠️  Necesitas estudiar más."
else
    echo "Insuficiente. Calificación: F ($calificacion)"
    echo "❌ Debes prepararte mejor para el próximo examen."
fi
EOF

$ chmod +x calificaciones.sh
$ ./calificaciones.sh
Introduce tu calificación (0-100):
85
¡Muy bien! Calificación: B (85)
👍 Buen trabajo, sigue así.

Operadores de Comparación

Bash ofrece diferentes operadores para comparar números, cadenas y archivos:

Comparaciones Numéricas

Operador Significado Ejemplo Verdadero si
-eq Igual a [ $a -eq $b ] a es igual a b
-ne No igual a [ $a -ne $b ] a no es igual a b
-gt Mayor que [ $a -gt $b ] a es mayor que b
-ge Mayor o igual que [ $a -ge $b ] a es mayor o igual que b
-lt Menor que [ $a -lt $b ] a es menor que b
-le Menor o igual que [ $a -le $b ] a es menor o igual que b

Comparaciones de Cadenas

Operador Significado Ejemplo Verdadero si
= Cadenas iguales [ "$a" = "$b" ] a es igual a b
!= Cadenas diferentes [ "$a" != "$b" ] a es diferente de b
-z Cadena vacía [ -z "$a" ] a está vacía
-n Cadena no vacía [ -n "$a" ] a no está vacía

Pruebas de Archivos

Operador Significado Ejemplo Verdadero si
-e Existe [ -e "$archivo" ] el archivo existe
-f Es archivo regular [ -f "$archivo" ] es un archivo regular
-d Es directorio [ -d "$directorio" ] es un directorio
-r Es legible [ -r "$archivo" ] tienes permiso de lectura
-w Es escribible [ -w "$archivo" ] tienes permiso de escritura
-x Es ejecutable [ -x "$archivo" ] tienes permiso de ejecución
# Ejemplos de diferentes tipos de comparaciones
$ cat > comparaciones_demo.sh << 'EOF'
#!/bin/bash

# Comparaciones numéricas
a=10
b=20
if [ $a -lt $b ]; then
    echo "$a es menor que $b"
fi

# Comparaciones de cadenas
usuario="admin"
if [ "$usuario" = "admin" ]; then
    echo "Acceso de administrador concedido"
fi

# Verificación de archivos
archivo="/etc/passwd"
if [ -f "$archivo" ]; then
    echo "El archivo $archivo existe y es un archivo regular"
    if [ -r "$archivo" ]; then
        echo "Y además puedo leerlo"
        echo "Primeras 3 líneas:"
        head -3 "$archivo"
    fi
fi

# Verificación de variables vacías
variable_vacia=""
if [ -z "$variable_vacia" ]; then
    echo "La variable está vacía"
fi
EOF

$ chmod +x comparaciones_demo.sh
$ ./comparaciones_demo.sh
10 es menor que 20
Acceso de administrador concedido
El archivo /etc/passwd existe y es un archivo regular
Y además puedo leerlo
Primeras 3 líneas:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin

Sintaxis Alternativa: [[ ]]

Bash ofrece una sintaxis extendida con [[ ]] que es más potente y flexible que [ ]:

Comparación: [ ] vs [[ ]] Copiar
# Sintaxis tradicional [ ]
if [ "$var" = "valor" ]; then
    echo "Coincidencia con [ ]"
fi

# Sintaxis extendida [[ ]]
if [[ $var == "valor" ]]; then
    echo "Coincidencia con [[ ]]"
fi

# Ventajas de [[ ]]
nombre="Juan Pérez"

# Con [ ] necesitas comillas obligatorias
if [ "$nombre" = "Juan Pérez" ]; then
    echo "Nombre correcto con [ ]"
fi

# Con [[ ]] las comillas son opcionales para variables
if [[ $nombre == "Juan Pérez" ]]; then
    echo "Nombre correcto con [[ ]]"
fi

# Patrones con [[ ]]
if [[ $nombre == Juan* ]]; then
    echo "El nombre empieza con 'Juan'"
fi

# Expresiones regulares con [[ ]]
if [[ $nombre =~ ^[A-Z][a-z]+ ]]; then
    echo "El nombre tiene formato válido"
fi
Portabilidad

[[ ]] es específico de Bash y no está disponible en todos los shells. Si necesitas compatibilidad con sh, usa [ ].

Casos Prácticos Reales

Script de validación de usuario Copiar
#!/bin/bash
# Script para validar y crear usuarios

echo "=== Sistema de Gestión de Usuarios ==="
echo "Introduce el nombre de usuario a crear:"
read nuevo_usuario

# Validar que no esté vacío
if [[ -z "$nuevo_usuario" ]]; then
    echo "❌ Error: El nombre de usuario no puede estar vacío."
    exit 1
fi

# Validar formato del usuario (solo letras y números)
if [[ ! $nuevo_usuario =~ ^[a-zA-Z][a-zA-Z0-9_]{2,31}$ ]]; then
    echo "❌ Error: Formato de usuario inválido."
    echo "   - Debe empezar con letra"
    echo "   - Solo letras, números y guiones bajos"
    echo "   - Entre 3 y 32 caracteres"
    exit 1
fi

# Verificar si el usuario ya existe
if id "$nuevo_usuario" &>/dev/null; then
    echo "⚠️  El usuario '$nuevo_usuario' ya existe."
    echo "¿Deseas ver su información? (s/n):"
    read respuesta
    
    if [[ $respuesta =~ ^[sS] ]]; then
        echo "Información del usuario:"
        id "$nuevo_usuario"
        getent passwd "$nuevo_usuario"
    fi
else
    echo "✅ El usuario '$nuevo_usuario' está disponible."
    echo "¿Deseas crearlo ahora? (s/n):"
    read crear
    
    if [[ $crear =~ ^[sS] ]]; then
        # Verificar si somos root
        if [[ $EUID -eq 0 ]]; then
            useradd -m "$nuevo_usuario"
            echo "✅ Usuario '$nuevo_usuario' creado exitosamente."
        else
            echo "⚠️  Necesitas permisos de root para crear usuarios."
            echo "Ejecuta: sudo useradd -m $nuevo_usuario"
        fi
    fi
fi
Monitor de espacio en disco Copiar
#!/bin/bash
# Monitor de espacio en disco con alertas

UMBRAL_CRITICO=90
UMBRAL_ADVERTENCIA=80
DIRECTORIO=${1:-/}

echo "=== Monitor de Espacio en Disco ==="
echo "Analizando: $DIRECTORIO"
echo "Umbrales: Advertencia=${UMBRAL_ADVERTENCIA}%, Crítico=${UMBRAL_CRITICO}%"
echo

# Obtener porcentaje de uso
uso=$(df "$DIRECTORIO" | awk 'NR==2 {print $5}' | sed 's/%//')

# Verificar si obtuvimos un número válido
if [[ ! $uso =~ ^[0-9]+$ ]]; then
    echo "❌ Error: No se pudo obtener información de $DIRECTORIO"
    exit 1
fi

echo "Uso actual: ${uso}%"

# Evaluar el nivel de uso
if [[ $uso -ge $UMBRAL_CRITICO ]]; then
    echo "🔴 CRÍTICO: Espacio en disco muy bajo!"
    echo "   Acción requerida inmediatamente."
    
    # Mostrar archivos más grandes
    echo
    echo "Archivos más grandes en $DIRECTORIO:"
    find "$DIRECTORIO" -type f -printf '%s %p\n' 2>/dev/null | sort -nr | head -5 | while read size path; do
        echo "   $(numfmt --to=iec $size) - $path"
    done
    
elif [[ $uso -ge $UMBRAL_ADVERTENCIA ]]; then
    echo "🟡 ADVERTENCIA: Espacio en disco bajo."
    echo "   Considera limpiar archivos innecesarios."
    
    # Sugerencias de limpieza
    echo
    echo "Sugerencias de limpieza:"
    if [[ -d /tmp ]]; then
        tmp_size=$(du -sh /tmp 2>/dev/null | cut -f1)
        echo "   - Limpiar /tmp (actualmente: $tmp_size)"
    fi
    
    if command -v apt-get >/dev/null; then
        echo "   - Ejecutar: sudo apt-get clean"
    fi
    
else
    echo "✅ NORMAL: Espacio en disco suficiente."
fi

# Mostrar información detallada
echo
echo "Detalles del sistema de archivos:"
df -h "$DIRECTORIO"

Ejercicios Prácticos

Ejercicio 1: Clasificador de Archivos

Crea un script que analice un archivo y determine su tipo y características:

clasificador_archivos.sh Copiar
#!/bin/bash
# Plantilla para ejercicio de clasificación de archivos

echo "Introduce la ruta del archivo a analizar:"
read archivo

# TODO: Verificar si el archivo existe
if [[ ___ ]]; then
    echo "❌ Error: El archivo no existe."
    exit 1
fi

# TODO: Determinar el tipo de archivo
if [[ ___ ]]; then
    echo "📁 Es un directorio"
    echo "   Contiene $(ls -1 "$archivo" | wc -l) elementos"
elif [[ ___ ]]; then
    echo "📄 Es un archivo regular"
    
    # TODO: Analizar el tamaño
    tamaño=$(stat -f%z "$archivo" 2>/dev/null || stat -c%s "$archivo" 2>/dev/null)
    
    if [[ $tamaño ___ 1048576 ]]; then  # 1MB
        echo "   📦 Archivo grande ($(numfmt --to=iec $tamaño))"
    elif [[ $tamaño ___ 1024 ]]; then  # 1KB
        echo "   📋 Archivo mediano ($(numfmt --to=iec $tamaño))"
    else
        echo "   📄 Archivo pequeño ($tamaño bytes)"
    fi
    
    # TODO: Verificar permisos
    if [[ -r "$archivo" ]]; then
        echo "   ✅ Legible"
    fi
    
    if [[ ___ ]]; then
        echo "   ✅ Escribible"
    fi
    
    if [[ ___ ]]; then
        echo "   ✅ Ejecutable"
    fi
    
else
    echo "❓ Tipo de archivo especial"
fi

# DESAFÍO: Agregar detección de extensión y tipo MIME
Ejercicio 2: Sistema de Login

Desarrolla un sistema básico de autenticación:

sistema_login.sh Copiar
#!/bin/bash
# Sistema de login básico

USUARIO_ADMIN="admin"
PASSWORD_ADMIN="secreto123"
USUARIO_INVITADO="guest"
PASSWORD_INVITADO="guest"

intentos=0
max_intentos=3

echo "=== Sistema de Acceso ==="

while [[ $intentos -lt $max_intentos ]]; do
    echo
    echo "Introduce tu usuario:"
    read usuario
    
    echo "Introduce tu contraseña:"
    read -s password  # -s oculta la entrada
    
    # TODO: Implementar la lógica de validación
    if [[ "$usuario" == "$USUARIO_ADMIN" && "$password" == "$PASSWORD_ADMIN" ]]; then
        echo
        echo "✅ Bienvenido, Administrador!"
        echo "Tienes acceso completo al sistema."
        break
    elif [[ ___ ]]; then
        echo
        echo "✅ Bienvenido, Invitado!"
        echo "Tienes acceso limitado al sistema."
        break
    else
        ((intentos++))
        restantes=$((max_intentos - intentos))
        
        if [[ $restantes -gt 0 ]]; then
            echo "❌ Credenciales incorrectas. Te quedan $restantes intentos."
        else
            echo "❌ Máximo de intentos alcanzado. Acceso bloqueado."
            exit 1
        fi
    fi
done

# TODO: Agregar funcionalidad específica según el tipo de usuario
Ejercicio Avanzado: Backup Inteligente

Crea un script de respaldo que tome decisiones basadas en múltiples condiciones: