En esta práctica trabajarás con una colección de scripts en Bash orientados a tareas básicas de automatización y administración en Linux. El objetivo es que ejecutes y analices cada uno de los scripts en tu terminal para comprender su funcionamiento y el efecto que producen.
Tareas a realizar
- Copia todos los scripts proporcionados en tu máquina Linux (física o virtual).
- Asegúrate de que cada script tenga permisos de ejecución usando:
chmod +x nombre_script.sh - Ejecuta cada script desde la terminal y observa el resultado.
- Modifica al menos 3 scripts para adaptarlos a una variante que tenga sentido. Por ejemplo:
- Cambiar rutas
- Cambiar comandos
- Añadir opciones
- Añadir colores o logs
La línea del “shebang” (#!)
#!/bin/bash#!/usr/bin/env bash
La diferencia tiene que ver con flexibilidad vs. certeza.
Cuando pones #!/bin/bash estás diciendo “usa Bash que está en /bin/bash”.
Eso asume que la ruta es exactamente esa. En muchas distros Linux es verdad, en macOS a veces también, pero en otras no. Por ejemplo, en sistemas BSD, en instalaciones personalizadas, o si manejas múltiples versiones de Bash instaladas desde brew, nix, etc., /bin/bash puede no existir o no ser el Bash que quieres.
La alternativa #!/usr/bin/env bash juega una carta distinta:env busca ejecutables en el PATH del usuario, encuentra dónde está bash y lo lanza.
Es como decir: “búscame un Bash válido en la ruta del sistema y úsalo”.
Eso lo vuelve más portátil y adaptable, sobre todo en entornos raros, macOS moderno, contenedores, virtual environments y setups educativos donde Bash no está donde uno espera.
El resumen práctico:
— #!/bin/bash = certero pero rígido. Si no existe esa ruta, falla.
— #!/usr/bin/env bash = más portable y respetuoso del PATH, útil cuando no conoces el entorno.
Ejemplo 1: “Hola, soy un script”
Propósito: variables y echo.
#!/usr/bin/env bash
nombre="Antonio"
echo "Hola, $nombre"
echo "Estoy en el directorio: $(pwd)"
Concepto nuevo: variables y comandos incrustados $(...).
Ejemplo 2: “Si me pasas un nombre, lo uso”
Propósito: argumentos $1.
#!/usr/bin/env bash
if [ -z "$1" ]; then
echo "Uso: $0 <nombre>"
exit 1
fi
echo "Hola, $1"
Concepto nuevo: if mínimo, chequeo de argumentos y exit.
Ejemplo 3: “Saludo a varios”
Propósito: recorrer argumentos (for).
#!/usr/bin/env bash
if [ "$#" -eq 0 ]; then
echo "Uso: $0 nombre1 nombre2 ..."
exit 1
fi
for persona in "$@"; do
echo "Hola, $persona"
done
Concepto nuevo: for y "$@" (todos los argumentos).
Ejemplo 4: “Saludo según hora”
Propósito: condicionales compuestos.
#!/usr/bin/env bash
hora=$(date +%H)
if [ "$hora" -lt 12 ]; then
saludo="Buenos días"
elif [ "$hora" -lt 20 ]; then
saludo="Buenas tardes"
else
saludo="Buenas noches"
fi
echo "$saludo, $(whoami)"
Concepto nuevo: elif, comparaciones numéricas y uso de comandos para info del sistema.
Pequeño ejemplo 5: “Función que loguea cosas”
Propósito: funciones y reutilización.
#!/usr/bin/env bash
log(){
echo "[$(date +%H:%M:%S)] $1"
}
log "Iniciando proceso"
sleep 1
log "Proceso terminado"
Concepto nuevo: funciones y timestamps.
Pequeño ejemplo 6: “Descargo URLs de una lista”
Propósito: arrays, loops y llamar programas externos.
Archivo urls.txt de ejemplo:
https://example.org
https://wikipedia.org
Script:
#!/usr/bin/env bash
while read -r url; do
[ -z "$url" ] && continue
echo "Descargando $url"
curl -s -O "$url"
done < urls.txt
Concepto nuevo: while read, redirección y pequeñas automatizaciones.
Ejemplo 7: “Contador de líneas de código por extensión”
Propósito: bucles, condicionales, comandos, pipes.
#!/usr/bin/env bash
if [ -z "$1" ]; then
echo "Uso: $0 <directorio>"
exit 1
fi
dir="$1"
for ext in sh py js php; do
total=$(find "$dir" -type f -name "*.$ext" -print0 | xargs -0 cat 2>/dev/null | wc -l)
echo "$ext: $total líneas"
done
Concepto nuevo: usar herramientas externas y procesar resultados.
Ejemplo 8: “Menú interactivo mínimo”
Propósito: select y control básico de flujo.
#!/usr/bin/env bash
select opcion in Fecha Usuario Salir; do
case "$opcion" in
Fecha) date ;;
Usuario) whoami ;;
Salir) echo "Adiós"; break ;;
*) echo "Opción no válida" ;;
esac
done
Concepto nuevo: select + case.
Pequeño ejemplo 9: “Backup comprimido con timestamp”
Propósito: combinación de todo para algo útil.
#!/usr/bin/env bash
origen="$1"
destino="$2"
if [ -z "$origen" ] || [ -z "$destino" ]; then
echo "Uso: $0 <directorio_origen> <directorio_destino>"
exit 1
fi
fecha=$(date +%Y%m%d_%H%M%S)
archivo="$destino/backup_$fecha.tar.gz"
echo "Creando backup de $origen en $archivo..."
tar -czf "$archivo" "$origen"
echo "Backup creado."
Ejemplo 10: Crear estructura de carpetas de proyecto
Idea: Montar la estructura típica de un proyecto sin ir haciendo mkdir a mano.
#!/usr/bin/env bash
if [ -z "$1" ]; then
echo "Uso: $0 <nombre_proyecto>"
exit 1
fi
PROYECTO="$1"
mkdir -p "$PROYECTO"/{src,bin,logs,tmp,docs}
echo "Proyecto creado en: $PROYECTO"
ls -R "$PROYECTO"
Ejemplo 11: Buscar una palabra en todos los .log de un directorio
Idea: Mini-grep para revisar logs del sistema o de una app.
#!/usr/bin/env bash
DIR="${1:-/var/log}"
CADENA="$2"
if [ -z "$CADENA" ]; then
echo "Uso: $0 <directorio_logs> <cadena_a_buscar>"
echo "Ejemplo: $0 /var/log error"
exit 1
fi
echo "Buscando '$CADENA' en *.log de $DIR..."
grep -Rni --include="*.log" "$CADENA" "$DIR"
Ejemplo 12: Top 5 archivos más grandes de un directorio
Idea: Visualizar qué archivos se están comiendo el disco.
#!/usr/bin/env bash
DIR="${1:-.}"
echo "Top 5 archivos más grandes en: $DIR"
du -ah "$DIR" 2>/dev/null | sort -h | tail -n 5
Ejemplo 13: Aviso sencillo de uso de disco
Idea: Script que comprueba / y avisa si pasa de cierto porcentaje.
#!/usr/bin/env bash
LIMITE=80 # porcentaje
uso=$(df -h / | awk 'NR==2 {gsub("%","",$5); print $5}')
echo "Uso actual de / : $uso%"
if [ "$uso" -gt "$LIMITE" ]; then
echo "⚠ Atención: uso de disco por encima de ${LIMITE}%"
else
echo "Todo OK, por debajo de ${LIMITE}%"
fi
Ejemplo 14: Copia rápida de syslog con timestamp
Idea: Guardar copia de seguridad de un log del sistema en el HOME del usuario.
#!/usr/bin/env bash
ORIGEN="/var/log/syslog"
DEST="$HOME"
if [ ! -f "$ORIGEN" ]; then
echo "No existe $ORIGEN (en algunas distros es /var/log/messages)"
exit 1
fi
FECHA=$(date +%Y%m%d_%H%M%S)
COPIA="$DEST/syslog_$FECHA.log"
cp "$ORIGEN" "$COPIA"
echo "Copia creada en: $COPIA"
Ejemplo 15: Ping-monitor cutre pero efectivo
Idea: Comprobar conectividad a un host cada pocos segundos.
#!/usr/bin/env bash
HOST="${1:-8.8.8.8}"
echo "Monitoreando ping a $HOST (Ctrl+C para salir)"
while true; do
if ping -c 1 -W 1 "$HOST" >/dev/null 2>&1; then
echo "[$(date +%H:%M:%S)] $HOST está accesible"
else
echo "[$(date +%H:%M:%S)] ⚠ $HOST NO responde"
fi
sleep 3
done
Ejemplo 16: Listar usuarios del sistema con su shell
Idea: Leer /etc/passwd y mostrar usuario + shell. Tocado sistema pero muy didáctico.
#!/usr/bin/env bash
echo "Usuarios del sistema y su shell:"
echo "--------------------------------"
while IFS=: read -r user _ _ _ _ _ shell; do
echo "$user -> $shell"
done < /etc/passwd
Ejemplo 17: Comprobar si un servicio está activo (systemd)
Idea: Ver el estado de un servicio con systemctl.
#!/usr/bin/env bash
if [ -z "$1" ]; then
echo "Uso: $0 <nombre_servicio>"
echo "Ejemplo: $0 apache2"
exit 1
fi
SERV="$1"
estado=$(systemctl is-active "$SERV" 2>/dev/null)
if [ "$estado" = "active" ]; then
echo "✅ El servicio $SERV está ACTIVO"
elif [ "$estado" = "inactive" ]; then
echo "⏸ El servicio $SERV está INACTIVO"
else
echo "❓ El servicio $SERV no existe o no usa systemd (estado: $estado)"
fi
Ejemplo 18: Renombrar archivos añadiendo un prefijo
Idea: Jugar con nombres de archivos y bucles. Muy útil para fotos, prácticas, etc.
#!/usr/bin/env bash
if [ "$#" -lt 2 ]; then
echo "Uso: $0 <prefijo> <archivos...>"
echo "Ejemplo: $0 practica1 *.txt"
exit 1
fi
PREFIJO="$1"
shift
for fichero in "$@"; do
if [ -f "$fichero" ]; then
nuevo="${PREFIJO}_$fichero"
mv "$fichero" "$nuevo"
echo "$fichero -> $nuevo"
else
echo "Saltando $fichero (no es un archivo)"
fi
done
Ejemplo 19: Menú para ver info básica del sistema
Idea: Un menú simple que llame a varios comandos de sistema.
#!/usr/bin/env bash
mostrar_sistema() {
echo "Sistema:"
uname -a
}
mostrar_cpu() {
echo "CPU:"
lscpu | head -n 10
}
mostrar_mem() {
echo "Memoria:"
free -h
}
mostrar_disks() {
echo "Discos:"
df -h
}
PS3="Elige una opción (1-5): "
select opcion in "Info sistema" "CPU" "Memoria" "Discos" "Salir"; do
case "$REPLY" in
1) mostrar_sistema ;;
2) mostrar_cpu ;;
3) mostrar_mem ;;
4) mostrar_disks ;;
5) echo "Adiós"; break ;;
*) echo "Opción no válida" ;;
esac
done








