⚙️ Automatizando Tareas con Bash Scripting I
Hoy vas a descubrir cómo usar Bash scripting para automatizar tareas en Linux. Desde chequeos básicos hasta reiniciar servicios automáticamente, ¡vas a empezar a pensar como un verdadero DevOps!
💻 ¿Dónde practicar?
Podés seguir esta clase usando:
- Tu propia terminal si tenés Linux o macOS
- WSL o Git Bash en Windows
- Un entorno virtual con Vagrant (como viste en el Día 3)
- O incluso 100% online con:
🧠 Fundamentos de Bash: Scripts y Condicionales
Antes de empezar con los scripts más útiles, veamos cómo funciona un script básico en Bash.
📄 ¿Qué es un script Bash?
Es un archivo de texto con instrucciones que ejecutás en una terminal Linux, como si las escribieras vos misma.
Ejemplo mínimo:
#!/bin/bash
echo "Hola Roxs DevOps!"
📌 Guardalo como hola.sh
, dale permisos y ejecutalo:
chmod +x hola.sh
./hola.sh
🔁 Estructura básica de un script
#!/bin/bash
# Comentario
echo "Hola Mundo"
# Variables
NOMBRE="Roxs"
echo "Hola $NOMBRE"
# Condicionales
if [ "$NOMBRE" == "Roxs" ]; then
echo "¡Sos vos!"
else
echo "¿Y vos quién sos?"
fi
# Bucle
for i in {1..3}; do
echo "Iteración $i"
done
✅ Condicionales comunes en Bash
Estructura | Explicación |
---|---|
if ...; then ... | Ejecuta si se cumple la condición |
else | Ejecuta si no se cumple |
elif | Evalúa una condición alternativa |
[ "$a" == "$b" ] | Compara cadenas |
[ $a -gt 5 ] | Mayor que (números) |
[ -f archivo ] | ¿Existe el archivo? |
[ -d carpeta ] | ¿Existe el directorio? |
🔃 Bucles útiles
Bucle for
for i in {1..5}; do
echo "Número: $i"
done
Bucle while
contador=1
while [ $contador -le 3 ]; do
echo "Contador: $contador"
((contador++))
done
🧪 Buenas prácticas
- Usá
#!/bin/bash
siempre en la primera línea - Usá
set -e
para salir si ocurre un error - Comentá tu código con
#
- Probá scripts en entornos controlados (como Vagrant o online)
Calentenemos motores
🐣 Primeros Pasos con Bash
Estos scripts te ayudarán a practicar los fundamentos de Bash antes de automatizar tareas más complejas.
✅ Script 1: ¡Hola Roxs!
#!/bin/bash
echo "Hola Roxs DevOps!"
💡 Este es tu primer script. Guardalo como hola.sh
, hacelo ejecutable con chmod +x hola.sh
y corrélo con ./hola.sh
.
📦 Script 2: Variables y Saludos
#!/bin/bash
NOMBRE="Roxs"
echo "Hola $NOMBRE, bienvenida al mundo DevOps"
📌 Las variables en Bash no usan let
, ni var
. Solo asignás con =
y sin espacios.
❓ Script 3: Preguntar al usuario
#!/bin/bash
echo "¿Cómo te llamás?"
read NOMBRE
echo "¡Hola $NOMBRE!"
📌 Usamos read
para capturar input del usuario. Guardalo como pregunta.sh
.
🔁 Script 4: Condicional simple
#!/bin/bash
read -p "¿Tenés sed? (sí/no): " RESPUESTA
if [ "$RESPUESTA" == "sí" ]; then
echo "Andá por un cafecito ☕"
else
echo "Seguimos con DevOps 🚀"
fi
💡 Usamos if
, then
, else
y fi
para crear condiciones.
🔂 Script 5: Bucle for
para repetir tareas
#!/bin/bash
for i in {1..5}; do
echo "DevOps es 🔥 - iteración $i"
done
🕵️ Script 6: Detectar si un archivo existe
#!/bin/bash
ARCHIVO="config.txt"
if [ -f "$ARCHIVO" ]; then
echo "El archivo $ARCHIVO existe"
else
echo "No encontré el archivo $ARCHIVO"
fi
💡 Muy útil para evitar errores al trabajar con archivos o scripts dependientes.
🧪 Sugerencia extra para practicar
Creá un script llamado mi_status.sh
que muestre:
- El nombre del usuario actual
- El directorio en el que estás
- La fecha y hora actual
#!/bin/bash
echo "Usuario: $(whoami)"
echo "Directorio actual: $(pwd)"
echo "Fecha: $(date)"
Si trabajas en DevOps o como administrador de sistemas, automatizar tareas rutinarias es esencial.
📁 Script 1: Monitoreo de Uso de Disco y Alertas 🚨
Problema: ¿Alguna vez se te llenó la partición raíz (/) sin aviso? Este script verifica:
Si la partición /
está al 90% o si /home
supera los 2GB.
#!/bin/bash
ADMIN="admin@ejemplo.com"
USO_RAIZ=$(df / | grep / | awk '{print $5}' | sed 's/%//g')
TAMANO_HOME=$(du -sh /home | awk '{print $1}' | sed 's/G//g')
if [ "$USO_RAIZ" -ge 90 ]; then
echo "¡Alerta: Partición / al ${USO_RAIZ}%!" | mail -s "Alerta Partición /" $ADMIN
fi
if (( $(echo "$TAMANO_HOME > 2" | bc -l) )); then
echo "¡Alerta: /home ocupa ${TAMANO_HOME}GB!" | mail -s "Alerta Directorio /home" $ADMIN
fi
📌 Programalo con cron para que corra cada hora:
0 * * * * /ruta/monitor_disco.sh
🔄 Script 2: Verificación y Reinicio de Servicios
Problema: ¿Tu servidor web (apache/nginx) se cae y no te das cuenta? Este script lo verifica y reinicia automáticamente.
Verifica si un servicio está caído y lo reinicia automáticamente.
#!/bin/bash
SERVICIO="apache2"
if ! systemctl is-active --quiet $SERVICIO; then
systemctl start $SERVICIO
echo "El servicio $SERVICIO fue reiniciado." | mail -s "Reinicio de $SERVICIO" admin@ejemplo.com
fi
📌 Cron sugerido:
* * * * * /ruta/monitor_servicio.sh
📊 Script 3: Monitoreo de Salud del Sistema
Reporte en tiempo real de uso de memoria, disco y CPU:
#!/bin/bash
TIEMPO=$(date "+%Y-%m-%d %H:%M:%S")
echo -e "Hora\t\t\tMemoria\t\tDisco (root)\tCPU"
segundos="3600"
fin=$((SECONDS+segundos))
while [ $SECONDS -lt $fin ]; do
MEMORIA=$(free -m | awk 'NR==2{printf "%.f%%\t\t", $3*100/$2 }')
DISCO=$(df -h | awk '$NF=="/"{printf "%s\t\t", $5}')
CPU=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{printf("%.f\n", 100 - $1)}')
echo -e "$TIEMPO\t$MEMORIA$DISCO$CPU"
sleep 3
done
📌 Podés guardar la salida en un archivo:
./monitor.sh >> /var/log/salud_sistema.log
📚 Tareas Opcionales del Día 4
Hoy diste tus primeros pasos con Bash. Ahora es momento de practicar de verdad. Elegí los desafíos que más te interesen... ¡o hacelos todos! 😉
🧪 Nivel 1: Calentando motores
-
✅ Crear un script llamado
presentacion.sh
que pida tu nombre y edad, y devuelva:Hola Roxs, tenés 30 años. ¡Bienvenida al mundo Bash!
-
✅ Creá un script
multiplicar.sh
que reciba dos números por argumento y muestre el resultado de la multiplicación. -
✅ Armá un bucle
for
que muestre la tabla del 5.
🧩 Nivel 2: Automatización útil
-
🛠 Creá un script
backup_logs.sh
que:- Comprima el contenido de
/var/log
- Lo guarde con timestamp en
/home/tu_usuario/backups/
- Elimine backups de más de 7 días
- Comprima el contenido de
-
🔍 Creá
buscar_palabra.sh
que:- Reciba un nombre de archivo y una palabra como argumentos
- Busque si la palabra aparece en el archivo (con
grep
) - Devuelva "¡Encontrado!" o "No encontrado."
🔥 Nivel 3: Reto DevOps Pro
-
🚀 Modificá
monitor_disco.sh
para que guarde un historial en un archivo log, incluyendo la fecha. -
🔁 Creá un
servicio_status.sh
que:- Revise varios servicios (
nginx
,mysql
,docker
) - Informe cuáles están activos y cuáles no
- Envíe un mail si alguno está caído (tip: usá un array y bucle)
- Revise varios servicios (
-
📈 Extendé el script de salud del sistema para que:
- Corte el monitoreo si la CPU supera el 85% tres veces seguidas
- O guarde un log separado llamado
alertas_cpu.log
💬 Bonus creativo
-
🎤 Hacé un script que sea un cuestionario loco:
- Preguntá el nombre, edad y color favorito
- Mostrá un mensaje personalizado según lo que responda
- Usá
if
,read
, y emojis enecho
💥
-
📸 Subí tu favorito a redes
- Captura de pantalla, gif o video corto
- Hashtag: #BashConRoxs o #DevOpsConRoxs
Material Extra
Accede al Repositorio Awesome Bash
Libro Recomendado introduction-to-bash-scripting
⚙️ Automatizando Tareas con Bash Scripting II
🧩 Parte 2: Técnicas Avanzadas con Bash
🔁 Funciones: Modularizando tus Scripts
Las funciones te permiten organizar y reutilizar lógica:
#!/bin/bash
saludar_usuario() {
echo "¡Hola, $1!"
}
saludar_usuario "Ana"
saludar_usuario "Carlos"
📌 Las funciones pueden ir al principio del script y luego las llamás donde las necesites.
📚 Manejo de Arrays
Los arrays sirven para manejar listas de elementos:
#!/bin/bash
archivos=("documento1.txt" "documento2.txt" "informe.pdf")
for archivo in "${archivos[@]}"; do
echo "Procesando $archivo"
done
❗ Manejo de Errores
Evitá que tu script falle silenciosamente:
#!/bin/bash
archivo="datos.csv"
if [[ -f $archivo ]]; then
echo "Leyendo $archivo"
cat "$archivo"
else
echo "Error: ¡$archivo no existe!"
exit 1
fi
🕒 Programación con Cron
Automatizá tus scripts en horarios definidos:
crontab -e
# Ejecutar cada día a las 2 AM
0 2 * * * /ruta/tu_script.sh
Usá crontab -l
para listar tus cron jobs activos.
🐞 Depuración de Scripts
Activá el modo debug para ver qué hace tu script paso a paso:
#!/bin/bash
set -x # Muestra cada comando antes de ejecutarlo
# Tu lógica aquí
Sumale set -e
para que el script se detenga ante errores:
set -e
🧠 Técnicas Bash Avanzadas
1. 🧪 Validación de Entradas
#!/bin/bash
if [[ $# -ne 1 ]]; then
echo "Uso: $0 <archivo>"
exit 1
fi
2. ⚙️ Manejo de Procesos en Segundo Plano
#!/bin/bash
proceso_largo() {
sleep 5
echo "Proceso completado"
}
proceso_largo &
pid=$!
wait $pid
3. 🔍 Expresiones Regulares con Bash
#!/bin/bash
texto="Usuario: María, Email: maria@ejemplo.com"
if [[ $texto =~ Usuario:\ ([^,]+),\ Email:\ ([^ ]+) ]]; then
usuario=${BASH_REMATCH[1]}
email=${BASH_REMATCH[2]}
echo "Usuario: $usuario, Email: $email"
fi
4. 🧵 Arrays Asociativos (Bash 4+)
#!/bin/bash
declare -A colores
colores[rojo]="#FF0000"
colores[verde]="#00FF00"
for color in "${!colores[@]}"; do
echo "$color: ${colores[$color]}"
done
5. 🔗 Integración con Herramientas Externas (ej. jq
)
#!/bin/bash
json='{"nombre": "Pedro", "edad": 28}'
nombre=$(echo "$json" | jq -r '.nombre')
edad=$(echo "$json" | jq -r '.edad')
echo "Nombre: $nombre, Edad: $edad"
📌 Asegurate de tener jq
instalado (sudo apt install jq
en Debian/Ubuntu).
6. 🧩 Scripts Modulares
Dividí tu lógica en archivos reutilizables:
# helpers.sh
function mostrar_ayuda() {
echo "Este script realiza..."
}
# principal.sh
#!/bin/bash
source ./helpers.sh
mostrar_ayuda
📝 Consejos Finales
- Usá
set -e
yset -x
para seguridad y debug - Validá argumentos y rutas antes de operar
- Comentá tus scripts para entenderlos después
- Usá ShellCheck para verificar errores
- Guardá tus scripts en un repo Git
🎯 Reto del Día 5
Automatización + modularidad + validación = nivel DevOps pro
📌 Objetivo: Crear un script llamado gestion_usuarios.sh
que permita:
- Crear un nuevo usuario pasando el nombre como argumento
- Validar si el usuario ya existe
- Registrar la acción en un log (
usuarios.log
) - Usar una función llamada
crear_usuario
definida en un archivofunciones.sh
Estructura sugerida:
funciones.sh
crear_usuario() {
if id "$1" &>/dev/null; then
echo "El usuario $1 ya existe."
else
sudo useradd "$1"
echo "Usuario $1 creado el $(date)" >> usuarios.log
echo "Usuario $1 creado."
fi
}
gestion_usuarios.sh
#!/bin/bash
source ./funciones.sh
if [[ $# -ne 1 ]]; then
echo "Uso: $0 <nombre_usuario>"
exit 1
fi
crear_usuario "$1"
🙌 Cuando termines, compartí tu captura con el log o el resultado del script con el hashtag #BashProConRoxs
--
💥 Bonus: Automatizá el Despliegue de la Aplicación Flask 📚"Book Library"📚 con Nginx y Gunicorn
¡En este desafío vas a crear un script de automatización completo que despliegue una aplicación Flask usando Gunicorn como servidor WSGI y Nginx como proxy inverso!
Este reto es clave para afianzar tus habilidades en scripting, automatización y despliegue.
🎯 Objetivo:
Crear un script llamado desplegar_app.sh
que realice automáticamente los siguientes pasos:
- ✅ Instale dependencias necesarias: Python, pip, virtualenv, Nginx y Git.
instalar_dependencias() {
sudo apt update
sudo apt install -y python3 python3-pip python3-venv nginx git
}
instalar_dependencias
-
🧱 Cree un entorno virtual, instale dependencias y clone la app:
git clone -b booklibrary https://github.com/roxsross/devops-static-web.git
cd devops-static-web
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
pip install gunicorn -
🚀 Configure Gunicorn para correr la app:
gunicorn -w 4 -b 127.0.0.1:8000 library_site:app:app
-
🌐 Configure Nginx para redirigir al puerto 8000 de Gunicorn.
-
🔄 Reinicie servicios y verifique que todo esté online.
-
📜 Guarde logs del proceso en
logs_despliegue.txt
📝 Ejemplo de desplegar_app.sh
#!/bin/bash
LOG="logs_despliegue.txt"
instalar_dependencias() {
echo "Instalando dependencias..." | tee -a $LOG
sudo apt update && sudo apt install -y python3 python3-pip python3-venv nginx git >> $LOG 2>&1
sudo systemctl enable nginx >> $LOG 2>&1
sudo systemctl start nginx >> $LOG 2>&1
}
clonar_app() {
echo "Clonando la aplicación..." | tee -a $LOG
git clone -b booklibrary https://github.com/roxsross/devops-static-web.git >> $LOG 2>&1
cd devops-static-web
}
configurar_entorno() {
echo "Configurando entorno virtual..." | tee -a ../$LOG
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt >> ../$LOG 2>&1
pip install gunicorn >> ../$LOG 2>&1
}
configurar_gunicorn() {
echo "Iniciando Gunicorn..." | tee -a ../$LOG
# CORREGIDO: Eliminar el :app extra
nohup venv/bin/gunicorn -w 4 -b 0.0.0.0:8000 library_site:app >> ../$LOG 2>&1 &
sleep 3 # Dar tiempo a que Gunicorn inicie
}
configurar_nginx() {
echo "Configurando Nginx..." | tee -a ../$LOG
# NUEVO: Eliminar configuración por defecto
sudo rm -f /etc/nginx/sites-enabled/default
# CORREGIDO: Usar 127.0.0.1:8000 en lugar de 0.0.0.0:8000
sudo tee /etc/nginx/sites-available/booklibrary > /dev/null <<EOF
server {
listen 80;
server_name _;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_redirect off;
}
location /static/ {
alias $(pwd)/static/;
expires 30d;
}
access_log /var/log/nginx/booklibrary_access.log;
error_log /var/log/nginx/booklibrary_error.log;
}
EOF
sudo ln -sf /etc/nginx/sites-available/booklibrary /etc/nginx/sites-enabled/
sudo nginx -t >> ../$LOG 2>&1 && sudo systemctl reload nginx
}
verificar_servicios() {
echo "Verificando servicios..." | tee -a ../$LOG
# Verificar Nginx
if systemctl is-active --quiet nginx; then
echo "✓ Nginx está activo" | tee -a ../$LOG
else
echo "✗ Nginx no está activo" | tee -a ../$LOG
fi
# Verificar Gunicorn
if pgrep -f "gunicorn.*library_site" > /dev/null; then
echo "✓ Gunicorn está corriendo" | tee -a ../$LOG
else
echo "✗ Gunicorn no está corriendo" | tee -a ../$LOG
fi
# Verificar puerto 8000
if netstat -tlnp | grep -q ":8000"; then
echo "✓ Puerto 8000 está en uso" | tee -a ../$LOG
else
echo "✗ Puerto 8000 no está en uso" | tee -a ../$LOG
fi
# Probar conexión directa a Gunicorn
if curl -s http://127.0.0.1:8000 > /dev/null; then
echo "✓ Gunicorn responde correctamente" | tee -a ../$LOG
else
echo "✗ Gunicorn no responde" | tee -a ../$LOG
fi
}
main() {
echo "=== Iniciando despliegue de Book Library ===" | tee $LOG
instalar_dependencias
clonar_app
configurar_entorno
configurar_gunicorn
configurar_nginx
verificar_servicios
echo "=== Despliegue finalizado ===" | tee -a ../$LOG
echo "Revisá $LOG para detalles." | tee -a ../$LOG
echo "La aplicación debería estar disponible en: http://$(hostname -I | awk '{print $1}')" | tee -a ../$LOG
}
main
🖼️ Resultados esperados
Para programar la verificación semanal con cron:
# Editá tu crontab con crontab -e y agregá:
0 3 * * 1 /ruta/desplegar_app.sh