Saltar al contenido principal

๐Ÿ“‹ Ejemplos โ€” Clase 02: Bash Scripting

Scripts listos para copiar y ejecutar en KillerCoda. Cada uno resuelve un caso real.


Ejemplo 1 โ€” Monitor de sistemaโ€‹

Un script que muestra un dashboard del servidor con colores.

monitor.sh
#!/bin/bash
VERDE='\033[0;32m'
ROJO='\033[0;31m'
AMARILLO='\033[1;33m'
CYAN='\033[0;36m'
NEGRITA='\033[1m'
NC='\033[0m'

clear
echo -e "${NEGRITA}${CYAN}"
echo "โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—"
echo "โ•‘ ๐Ÿ“Š MONITOR DE SISTEMA โ•‘"
echo "โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
echo -e "${NC}"

# Hostname e IP
echo -e "${NEGRITA}๐Ÿ–ฅ๏ธ Host:${NC} $(hostname)"
IP=$(hostname -I 2>/dev/null | awk '{print $1}')
echo -e "${NEGRITA}๐ŸŒ IP:${NC} ${IP:-N/A}"
echo -e "${NEGRITA}๐Ÿ‘ค User:${NC} $(whoami)"
echo -e "${NEGRITA}๐Ÿ“… Fecha:${NC} $(date '+%d/%m/%Y %H:%M:%S')"
echo ""

# Uptime
UPTIME=$(uptime -p 2>/dev/null || uptime)
echo -e "${NEGRITA}โฑ๏ธ Uptime:${NC} $UPTIME"
echo ""

# CPU
echo -e "${NEGRITA}${CYAN}โ”€โ”€ CPU โ”€โ”€${NC}"
LOAD=$(cat /proc/loadavg | awk '{print $1}')
CORES=$(nproc 2>/dev/null || echo "?")
echo -e " Load average: ${AMARILLO}$LOAD${NC} ($CORES cores)"
echo ""

# Memoria
echo -e "${NEGRITA}${CYAN}โ”€โ”€ MEMORIA โ”€โ”€${NC}"
if command -v free &>/dev/null; then
TOTAL=$(free -h | awk '/Mem:/{print $2}')
USADO=$(free -h | awk '/Mem:/{print $3}')
LIBRE=$(free -h | awk '/Mem:/{print $4}')
PCT=$(free | awk '/Mem:/{printf "%.0f", $3/$2*100}')

if [ "$PCT" -gt 80 ]; then
COLOR=$ROJO
elif [ "$PCT" -gt 50 ]; then
COLOR=$AMARILLO
else
COLOR=$VERDE
fi
echo -e " Total: $TOTAL | Usado: ${COLOR}$USADO ($PCT%)${NC} | Libre: $LIBRE"
fi
echo ""

# Disco
echo -e "${NEGRITA}${CYAN}โ”€โ”€ DISCO โ”€โ”€${NC}"
df -h / | awk 'NR==2{
printf " Total: %s | Usado: %s (%s) | Libre: %s\n", $2, $3, $5, $4
}'
echo ""

# Servicios
echo -e "${NEGRITA}${CYAN}โ”€โ”€ SERVICIOS โ”€โ”€${NC}"
for SVC in nginx apache2 ssh; do
if systemctl is-active --quiet $SVC 2>/dev/null; then
echo -e " ${VERDE}โ— $SVC${NC} โ€” corriendo"
else
echo -e " ${ROJO}โ—‹ $SVC${NC} โ€” detenido"
fi
done
echo ""

# Top 5 procesos
echo -e "${NEGRITA}${CYAN}โ”€โ”€ TOP 5 PROCESOS (por CPU) โ”€โ”€${NC}"
ps aux --sort=-%cpu | head -6 | awk 'NR>1{printf " %-8s %5s%% CPU %5s%% MEM %s\n", $1, $3, $4, $11}'
echo ""
echo -e "${CYAN}โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”${NC}"

Ejemplo 2 โ€” Logger con timestampsโ€‹

Un sistema de logging reutilizable para tus scripts.

logger.sh
#!/bin/bash
# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
# ๐Ÿ“ Sistema de Logging para Scripts
# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

LOG_FILE="/var/log/mi-script.log"
VERDE='\033[0;32m'
ROJO='\033[0;31m'
AMARILLO='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

log() {
local NIVEL="$1"
local MENSAJE="$2"
local TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

# Escribir al archivo (sin colores)
echo "[$TIMESTAMP] [$NIVEL] $MENSAJE" >> "$LOG_FILE"

# Mostrar en pantalla (con colores)
case $NIVEL in
INFO) echo -e "${CYAN}[$TIMESTAMP] [INFO]${NC} $MENSAJE";;
OK) echo -e "${VERDE}[$TIMESTAMP] [OK]${NC} $MENSAJE";;
WARN) echo -e "${AMARILLO}[$TIMESTAMP] [WARN]${NC} $MENSAJE";;
ERROR) echo -e "${ROJO}[$TIMESTAMP] [ERROR]${NC} $MENSAJE";;
esac
}

# โ”€โ”€ Uso โ”€โ”€
log "INFO" "Script iniciado"
log "INFO" "Verificando Nginx..."

if command -v nginx &>/dev/null; then
log "OK" "Nginx estรก instalado"
else
log "WARN" "Nginx no encontrado, instalando..."
apt update -qq && apt install nginx -y -qq
log "OK" "Nginx instalado"
fi

if systemctl is-active --quiet nginx 2>/dev/null; then
log "OK" "Nginx estรก corriendo"
else
log "WARN" "Nginx detenido, iniciando..."
systemctl start nginx
log "OK" "Nginx iniciado"
fi

log "INFO" "Script finalizado"
echo ""
echo "๐Ÿ“„ Log guardado en: $LOG_FILE"

Ejemplo 3 โ€” Generador de sitios estรกticosโ€‹

Un mini generador que crea un sitio completo a partir de archivos Markdown (simulado).

generar-sitio.sh
#!/bin/bash
VERDE='\033[0;32m'
CYAN='\033[0;36m'
NC='\033[0m'

SITIO="/var/www/generado"
TITULO="Mi Blog DevOps"

echo -e "${CYAN}๐Ÿ”จ Generador de Sitio Estรกtico${NC}\n"

mkdir -p "$SITIO"

# Funciรณn para generar una pรกgina
generar_pagina() {
local ARCHIVO="$1"
local TITULO_PAG="$2"
local CONTENIDO="$3"
local EMOJI="$4"

cat > "$SITIO/$ARCHIVO" << EOF
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>$TITULO_PAG โ€” $TITULO</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Segoe UI', sans-serif; background: #0f172a; color: #e2e8f0; }
nav {
background: #1e293b; padding: 1rem 2rem;
display: flex; gap: 1.5rem; align-items: center;
border-bottom: 1px solid #334155;
}
nav .brand { font-weight: bold; color: #00ff87; font-size: 1.1rem; }
nav a { color: #94a3b8; text-decoration: none; font-size: 0.9rem; }
nav a:hover { color: #00d4ff; }
main { max-width: 700px; margin: 3rem auto; padding: 0 2rem; }
h1 { font-size: 2.2rem; margin-bottom: 1rem; }
h1 .emoji { margin-right: 0.5rem; }
p { line-height: 1.8; color: #94a3b8; margin-bottom: 1rem; }
code {
background: #1e293b; padding: 0.15rem 0.4rem;
border-radius: 4px; font-size: 0.9rem; color: #00d4ff;
}
footer {
text-align: center; padding: 2rem;
color: #475569; font-size: 0.8rem;
border-top: 1px solid #1e293b; margin-top: 4rem;
}
</style>
</head>
<body>
<nav>
<span class="brand">$TITULO</span>
<a href="/">Inicio</a>
<a href="/linux.html">Linux</a>
<a href="/nginx.html">Nginx</a>
<a href="/bash.html">Bash</a>
</nav>
<main>
<h1><span class="emoji">$EMOJI</span>$TITULO_PAG</h1>
$CONTENIDO
</main>
<footer>Generado con Bash โ€” DevOps Bootcamp by ROXS</footer>
</body>
</html>
EOF
echo -e "${VERDE} โœ… $ARCHIVO${NC}"
}

# Generar pรกginas
generar_pagina "index.html" "Bienvenido" \
"<p>Este sitio fue generado automรกticamente con un script de Bash. Cada pรกgina es un archivo HTML independiente.</p><p>Explorรก las secciones del menรบ para aprender sobre Linux, Nginx y Bash.</p>" "๐Ÿ "

generar_pagina "linux.html" "Comandos Linux" \
"<p>Los comandos mรกs usados en Linux:</p><p><code>ls</code> โ€” listar archivos</p><p><code>cd</code> โ€” cambiar directorio</p><p><code>mkdir</code> โ€” crear carpeta</p><p><code>cat</code> โ€” ver contenido</p><p><code>chmod</code> โ€” cambiar permisos</p>" "๐Ÿง"

generar_pagina "nginx.html" "Nginx" \
"<p>Nginx es el servidor web mรกs popular del mundo. Se usa para servir sitios estรกticos, como reverse proxy y como balanceador de carga.</p><p>Config principal: <code>/etc/nginx/nginx.conf</code></p><p>Sitios: <code>/etc/nginx/sites-available/</code></p>" "โšก"

generar_pagina "bash.html" "Bash Scripting" \
"<p>Bash es el intรฉrprete de comandos de Linux. Con scripts podรฉs automatizar tareas repetitivas.</p><p>Siempre empezรก con: <code>#!/bin/bash</code></p><p>Hacelo ejecutable: <code>chmod +x script.sh</code></p>" "๐Ÿ“œ"

echo -e "\n${VERDE}โœ… Sitio generado en $SITIO (4 pรกginas)${NC}"

Ejemplo 4 โ€” Watcher de archivosโ€‹

Un script que vigila cambios en una carpeta y ejecuta acciones.

watcher.sh
#!/bin/bash
# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
# ๐Ÿ‘๏ธ File Watcher โ€” Vigila cambios
# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

VERDE='\033[0;32m'
AMARILLO='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

DIRECTORIO="${1:-/var/www}"
INTERVALO=5

echo -e "${CYAN}๐Ÿ‘๏ธ Vigilando: $DIRECTORIO${NC}"
echo -e "${CYAN} Intervalo: cada ${INTERVALO}s${NC}"
echo -e "${CYAN} Ctrl+C para detener${NC}\n"

# Snapshot inicial
SNAPSHOT_ANTERIOR=$(find "$DIRECTORIO" -type f -exec md5sum {} \; 2>/dev/null | sort)

while true; do
sleep $INTERVALO

SNAPSHOT_ACTUAL=$(find "$DIRECTORIO" -type f -exec md5sum {} \; 2>/dev/null | sort)

if [ "$SNAPSHOT_ANTERIOR" != "$SNAPSHOT_ACTUAL" ]; then
TIMESTAMP=$(date '+%H:%M:%S')
echo -e "${AMARILLO}[$TIMESTAMP] ๐Ÿ”„ Cambio detectado en $DIRECTORIO${NC}"

# Mostrar archivos nuevos
NUEVOS=$(diff <(echo "$SNAPSHOT_ANTERIOR" | awk '{print $2}') \
<(echo "$SNAPSHOT_ACTUAL" | awk '{print $2}') \
| grep "^>" | awk '{print $2}')

if [ -n "$NUEVOS" ]; then
echo -e "${VERDE} Archivos nuevos:${NC}"
echo "$NUEVOS" | while read F; do
echo -e " ${VERDE}+ $F${NC}"
done
fi

# Acciรณn: recargar Nginx si hay cambios en HTML
if echo "$SNAPSHOT_ACTUAL" | grep -q "\.html"; then
if systemctl is-active --quiet nginx 2>/dev/null; then
systemctl reload nginx 2>/dev/null
echo -e "${VERDE} โ†ป Nginx recargado${NC}"
fi
fi

SNAPSHOT_ANTERIOR="$SNAPSHOT_ACTUAL"
fi
done
chmod +x watcher.sh
./watcher.sh /var/www/mi-sitio

Ejemplo 5 โ€” Instalador de herramientas DevOpsโ€‹

Un script que instala las herramientas bรกsicas para DevOps.

setup-devops.sh
#!/bin/bash
VERDE='\033[0;32m'
ROJO='\033[0;31m'
CYAN='\033[0;36m'
NEGRITA='\033[1m'
NC='\033[0m'

exito() { echo -e "${VERDE} โœ… $1${NC}"; }
error() { echo -e "${ROJO} โŒ $1${NC}"; }
info() { echo -e "${CYAN} โ„น๏ธ $1${NC}"; }

clear
echo -e "${NEGRITA}${CYAN}"
echo "โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—"
echo "โ•‘ ๐Ÿ› ๏ธ Setup DevOps โ€” Herramientas โ•‘"
echo "โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•"
echo -e "${NC}\n"

# Verificar root
if [ "$EUID" -ne 0 ]; then
error "Ejecutรก con sudo: sudo ./setup-devops.sh"
exit 1
fi

info "Actualizando paquetes..."
apt update -qq 2>/dev/null

# Lista de herramientas
HERRAMIENTAS=(
"curl:Transferencia de datos"
"wget:Descargar archivos"
"git:Control de versiones"
"vim:Editor de texto"
"htop:Monitor de procesos"
"tree:รrbol de directorios"
"jq:Procesar JSON"
"unzip:Descomprimir ZIP"
"nginx:Servidor web"
"net-tools:Herramientas de red"
)

INSTALADOS=0
TOTAL=${#HERRAMIENTAS[@]}

for ITEM in "${HERRAMIENTAS[@]}"; do
PKG=$(echo "$ITEM" | cut -d: -f1)
DESC=$(echo "$ITEM" | cut -d: -f2)

if command -v "$PKG" &>/dev/null || dpkg -l "$PKG" &>/dev/null 2>&1; then
exito "$PKG โ€” $DESC (ya instalado)"
((INSTALADOS++))
else
info "Instalando $PKG โ€” $DESC..."
if apt install "$PKG" -y -qq 2>/dev/null; then
exito "$PKG instalado"
((INSTALADOS++))
else
error "No se pudo instalar $PKG"
fi
fi
done

echo ""
echo -e "${NEGRITA}${CYAN}โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”${NC}"
echo -e "${VERDE} โœ… $INSTALADOS/$TOTAL herramientas listas${NC}"
echo -e "${NEGRITA}${CYAN}โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”${NC}"

Ejemplo 6 โ€” Cheat sheet de Bashโ€‹

Referencia rรกpida de Bash scripting.

# โ•โ•โ• VARIABLES โ•โ•โ•
NOMBRE="valor" # Crear (sin espacios en =)
echo "$NOMBRE" # Usar
echo "${NOMBRE}_sufijo" # Con llaves para concatenar
FECHA=$(date +%Y-%m-%d) # Resultado de comando
PUERTO=${1:-80} # Argumento con default

# โ•โ•โ• CONDICIONALES โ•โ•โ•
if [ "$A" == "$B" ]; then # Comparar strings
if [ "$A" -gt 10 ]; then # Mayor que (nรบmeros)
if [ -f "/ruta" ]; then # ยฟExiste archivo?
if [ -d "/ruta" ]; then # ยฟExiste directorio?
if [ -z "$VAR" ]; then # ยฟEstรก vacรญa?
if command -v nginx; then # ยฟEstรก instalado?

# โ•โ•โ• LOOPS โ•โ•โ•
for I in 1 2 3 4 5; do echo $I; done
for F in *.html; do echo $F; done
for I in $(seq 1 10); do echo $I; done
while true; do echo "loop"; sleep 1; done
while read LINEA; do echo $LINEA; done < archivo.txt

# โ•โ•โ• FUNCIONES โ•โ•โ•
mi_funcion() {
echo "Argumento 1: $1"
echo "Argumento 2: $2"
return 0
}
mi_funcion "hola" "mundo"

# โ•โ•โ• STRINGS โ•โ•โ•
echo ${#NOMBRE} # Longitud
echo ${NOMBRE^^} # MAYรšSCULAS
echo ${NOMBRE,,} # minรบsculas
echo ${NOMBRE/viejo/nuevo} # Reemplazar

# โ•โ•โ• ARRAYS โ•โ•โ•
LISTA=("uno" "dos" "tres")
echo ${LISTA[0]} # Primer elemento
echo ${LISTA[@]} # Todos
echo ${#LISTA[@]} # Cantidad

# โ•โ•โ• REDIRECCIร“N โ•โ•โ•
comando > archivo # Sobreescribir
comando >> archivo # Agregar al final
comando 2>/dev/null # Ocultar errores
comando &>/dev/null # Ocultar todo
comando | otro_comando # Pipe

# โ•โ•โ• ESPECIALES โ•โ•โ•
$0 # Nombre del script
$1, $2, $3 # Argumentos
$# # Cantidad de argumentos
$? # Exit code del รบltimo comando
$$ # PID del script
$@ # Todos los argumentos

๐Ÿ”— Recursosโ€‹