Qué vas a conseguir
Un script de Bash que puedes dejar en cualquier servidor Linux y que, cada mañana, te dice si el disco se llena, si un servicio se ha caído o si la carga está disparada. Y, de paso, las reglas de escritura que separan un script que ayuda de uno que un día borra algo.
Antes de empezar
- Un servidor Linux (Ubuntu, RHEL, Debian) con acceso por SSH y
sudo. - Un editor:
nanovale para empezar;vimcuando quieras. - Para probar, un directorio propio:
mkdir -p ~/scripts.
1. Las cinco reglas
- Empieza siempre igual:
#!/usr/bin/env bashyset -euo pipefail. Para en el primer error (-e), falla si usas una variable no definida (-u) y no esconde errores en una tubería (-o pipefail). - Comillas en las variables:
"$ruta", nunca$ruta. Un espacio en un nombre de archivo y unrmsin comillas es cómo se pierden carpetas. - Nunca
rm -rfsobre una variable sin comprobar antes que no está vacía y que apunta a donde crees:[[ -n "$dir" && "$dir" != "/" ]]. - Primero en modo lectura. Un script que solo lee y avisa no puede romper nada. Lo que escribe (borrar logs, reiniciar servicios) se añade después, con
--applyexplícito. - Pásalo por
shellcheckantes de ejecutarlo en un servidor. Encuentra los errores clásicos que el ojo no ve.
2. El script
#!/usr/bin/env bashset -euo pipefail DISK_MAX=85 # % de uso de disco a partir del que avisaLOAD_MAX=4 # carga media de 5 minSERVICES=(sshd cron) # servicios que deben estar activosSTATUS=0 warn() { echo "AVISO: $*"; STATUS=1; } echo "== $(hostname) · $(date '+%d/%m/%Y %H:%M') ==" # Disco: cada sistema de ficheros real por encima del umbralwhile read -r fs use mount; do use=${use%\%} (( use >= DISK_MAX )) && warn "disco $mount al $use% ($fs)"done < <(df -h --output=source,pcent,target -x tmpfs -x devtmpfs | tail -n +2) # Memoria y cargaread -r _ total used _ < <(free -m | awk '/^Mem:/')echo "memoria: $used/$total MB"load=$(cut -d' ' -f2 /proc/loadavg)awk -v l="$load" -v m="$LOAD_MAX" 'BEGIN{exit !(l>=m)}' && warn "carga a 5 min: $load" # Serviciosfor s in "${SERVICES[@]}"; do systemctl is-active --quiet "$s" || warn "servicio $s no está activo"done (( STATUS == 0 )) && echo "OK: sin avisos"exit $STATUSNotas sobre lo que hace: df --output evita tener que contar columnas; tail -n +2 salta la cabecera; ${use%\%} quita el %; read ... < <(...) lee de un comando sin abrir una subshell (así STATUS sí cambia dentro del bucle). La comparación de la carga va con awk porque Bash no compara decimales.
3. Probar
chmod +x ~/scripts/check-server.shshellcheck ~/scripts/check-server.sh && echo "shellcheck ok"shellcheck ok~/scripts/check-server.sh== srv-files-01 · 21/10/2026 08:00 ==AVISO: disco /var al 91% (/dev/sda3)memoria: 3105/7812 MBAVISO: servicio cron no está activoecho $?1El código de salida (1 con avisos, 0 sin ellos) es lo que permite que cron, un monitor o otro script sepan si ha ido bien sin leer el texto.
4. Programarlo
sudo cp ~/scripts/check-server.sh /usr/local/bin/check-serversudo crontab -e# cada día a las 7:00, guardando la salida en un log que rota0 7 * * * /usr/local/bin/check-server >> /var/log/check-server.log 2>&1sudo tail -n 20 /var/log/check-server.logEn cron no hay tu PATH ni tus alias: usa rutas completas y prueba el script con env -i bash -c /usr/local/bin/check-server para ver cómo se comporta sin tu entorno. Para que avise por correo, MAILTO=it@contoso.com al principio del crontab (si el servidor tiene correo configurado), o mejor, que escriba en el log que ya recoge tu monitorización.
Siguientes pasos
- Añade un
--applyque haga algo útil y seguro: rotar un log, reiniciar el servicio caído consystemctl restart. - Pon el script en el repositorio del equipo (guía de Git) para que cambie con revisión y no por SSH a mano.
- En el Nivel 3 verás Ansible: cuando el mismo script tiene que correr en 40 servidores, es su trabajo.
¿Falta algo o en tu entorno es distinto? Escríbeme y lo corrijo.
Tech Career Lab · newsletter
¿Te ha servido? Cada dos semanas envío una idea práctica para perfiles IT: LinkedIn, proyectos, networking y procesos de selección.
Apúntate y llévate las 33 ideas →