Clase 04 — Bucles (Loops)
for — Iterar sobre una lista
#!/bin/bash
# Iterar sobre lista de palabras
for fruta in manzana pera uva naranja; do
echo "Fruta: $fruta"
done
# Iterar sobre un rango
for i in {1..5}; do
echo "Número: $i"
done
# Rango con paso
for i in {0..20..5}; do
echo "Valor: $i"
done
# Estilo C
for ((i = 0; i < 5; i++)); do
echo "Índice: $i"
done
for — Iterar sobre archivos
#!/bin/bash
# Todos los archivos .sh del directorio actual
for archivo in *.sh; do
echo "Script encontrado: $archivo"
done
# Archivos en un directorio específico
for f in /tmp/*; do
if [[ -f "$f" ]]; then
echo "Archivo: $(basename "$f")"
fi
done
# Iterar recursivamente
for f in $(find . -name "*.txt" -type f); do
echo "Encontrado: $f"
done
for — Iterar con la salida de un comando
#!/bin/bash
# Iterar sobre líneas de un comando
for usuario in $(cut -d: -f1 /etc/passwd | head -5); do
echo "Usuario: $usuario"
done
# Iterar sobre argumentos del script
for arg in "$@"; do
echo "Argumento: $arg"
done
while — Mientras se cumpla la condición
#!/bin/bash
# Contador
contador=1
while [[ $contador -le 5 ]]; do
echo "Iteración: $contador"
((contador++))
done
# Leer archivo línea por línea (forma recomendada)
while IFS= read -r linea; do
echo "Línea: $linea"
done < archivo.txt
# Bucle infinito con condición de salida
intentos=0
while true; do
((intentos++))
echo "Intento #$intentos"
if [[ $intentos -ge 3 ]]; then
echo "Máximo de intentos alcanzado"
break
fi
done
until — Hasta que se cumpla la condición
#!/bin/bash
# until es el opuesto de while
contador=1
until [[ $contador -gt 5 ]]; do
echo "Contador: $contador"
((contador++))
done
Ejemplo: Esperar a que un servicio esté disponible
#!/bin/bash
# wait-service.sh - Esperar hasta que un host responda
HOST="${1:-localhost}"
PORT="${2:-8080}"
MAX_INTENTOS=10
intento=0
echo "Esperando a que $HOST:$PORT esté disponible..."
until nc -z "$HOST" "$PORT" 2>/dev/null; do
((intento++))
if [[ $intento -ge $MAX_INTENTOS ]]; then
echo "ERROR: $HOST:$PORT no respondió después de $MAX_INTENTOS intentos"
exit 1
fi
echo " Intento $intento/$MAX_INTENTOS - Reintentando en 2s..."
sleep 2
done
echo "$HOST:$PORT está disponible!"
break y continue
#!/bin/bash
# break - Salir del bucle
echo "=== BREAK ==="
for i in {1..10}; do
if [[ $i -eq 5 ]]; then
echo "Detenido en $i"
break
fi
echo "Número: $i"
done
echo ""
# continue - Saltar a la siguiente iteración
echo "=== CONTINUE ==="
for i in {1..10}; do
if (( i % 2 == 0 )); then
continue # Saltar números pares
fi
echo "Impar: $i"
done
select — Menú interactivo
#!/bin/bash
echo "Seleccioná tu lenguaje favorito:"
select lenguaje in Python JavaScript Go Rust "Salir"; do
case $lenguaje in
Python)
echo "Elegiste Python - Ideal para DevOps!"
;;
JavaScript)
echo "Elegiste JavaScript - Full Stack!"
;;
Go)
echo "Elegiste Go - Cloud Native!"
;;
Rust)
echo "Elegiste Rust - Performance!"
;;
"Salir")
echo "¡Adiós!"
break
;;
*)
echo "Opción inválida. Intentá de nuevo."
;;
esac
done
Ejemplo práctico: Monitor de procesos
#!/bin/bash
# monitor.sh - Monitorea el uso de CPU cada N segundos
INTERVALO=${1:-5}
ITERACIONES=${2:-5}
echo "======================================"
echo " MONITOR DE SISTEMA"
echo " Intervalo: ${INTERVALO}s"
echo " Iteraciones: $ITERACIONES"
echo "======================================"
for ((i = 1; i <= ITERACIONES; i++)); do
echo ""
echo "--- Snapshot #$i [$(date '+%H:%M:%S')] ---"
echo "Procesos activos: $(ps aux | wc -l)"
echo "Carga del sistema: $(uptime | awk -F'load average:' '{print $2}')"
echo "Memoria:"
if [[ "$(uname)" == "Darwin" ]]; then
vm_stat | head -5
else
free -h | grep Mem
fi
if [[ $i -lt $ITERACIONES ]]; then
sleep "$INTERVALO"
fi
done
echo ""
echo "Monitoreo finalizado."
Ejemplo práctico: Procesador de logs
#!/bin/bash
# procesar-logs.sh - Procesa y resume un archivo de log
LOG_FILE="${1:-/var/log/syslog}"
if [[ ! -f "$LOG_FILE" ]]; then
echo "Archivo no encontrado: $LOG_FILE"
exit 1
fi
total=0
errores=0
warnings=0
while IFS= read -r linea; do
((total++))
if [[ "$linea" == *"error"* ]] || [[ "$linea" == *"ERROR"* ]]; then
((errores++))
elif [[ "$linea" == *"warn"* ]] || [[ "$linea" == *"WARN"* ]]; then
((warnings++))
fi
done < "$LOG_FILE"
echo "=============================="
echo " RESUMEN DE LOG"
echo "=============================="
echo "Archivo : $LOG_FILE"
echo "Total : $total líneas"
echo "Errores : $errores"
echo "Warnings : $warnings"
echo "Otros : $((total - errores - warnings))"
echo "=============================="
Bucles anidados
#!/bin/bash
# Tabla de multiplicar
echo "TABLA DE MULTIPLICAR (1-5)"
echo ""
for i in {1..5}; do
for j in {1..5}; do
printf "%4d" $((i * j))
done
echo ""
done
Ejercicios
- Creá un script que imprima los números del 1 al 100 que sean divisibles por 3 y 5
- Creá un script que recorra todos los archivos de un directorio y muestre su tamaño
- Creá un "countdown" que cuente de 10 a 0 con un
sleep 1entre cada número - Creá un script que lea un archivo CSV y muestre cada campo formateado