Introducción a los scripts Bash: guía paso a paso con ejemplos

Introducción a los scripts Bash: guía paso a paso con ejemplos

Las operaciones repetitivas consumen tiempo y atención. Uno o dos scripts Bash pueden liberar del clic repetitivo en el gestor de archivos, acelerar las copias de seguridad o automatizar el despliegue de proyectos. En este artículo — el conjunto básico completo: variables, if, for, funciones, arrays, manejo de argumentos, depuración y escenarios prácticos.

Qué es Bash y por qué es útil

Bash (Bourne Again Shell) — la shell de comandos estándar en Linux, macOS, sistemas tipo Unix y WSL de Windows. Se usa mucho por administradores, ingenieros DevOps, desarrolladores y entusiastas gracias a:

  • Disponibilidad — viene preinstalada casi en todas partes o se instala con un solo comando.
  • Integración — se combina fácilmente con utilidades (grepawksed, curl).
  • Automatización — los scripts se guardan en Git, se ejecutan desde CI y por programación mediante cron.

Preparación mínima

Asegúrese de que:

  1. El archivo comienza con la línea shebang #!/usr/bin/env bash.
  2. El archivo tiene permiso de ejecución: chmod +x myscript.sh.
  3. Se puede ejecutar de dos maneras:
    bash myscript.sh o ./myscript.sh.

Modo estricto de errores

Añada al inicio del script:

set -euo pipefail

Las opciones significan: detenerse al ocurrir un error (-e), tratar como error las variables no declaradas (-u), no ignorar errores en pipes (pipefail).

Variables: fundamento de la flexibilidad

Declaración y uso

NAME="María"
echo "¡Hola, $NAME!"
BACKUP_DIR="/backups/$(date +%F)"

Sustitución de comandos

La expresión $(…) inserta la salida de un comando:

FILES=$(ls | wc -l)
echo "Hay $FILES archivos en el directorio"

Lectura de entrada del usuario

read -rp "Introduzca la ruta al directorio: " DIR
echo "Contenido de $DIR:"
ls "$DIR"

Operadores condicionales if

Plantilla básica:

if [[ -f "settings.cfg" ]]; then
  echo "Configuración encontrada"
else
  echo "Archivo no encontrado"
  exit 1
fi

Ejemplos ampliados

  • Comprobación de cadena: [[ -z "$VAR" ]] — si la cadena está vacía.
  • Números: [[ $A -gt 10 ]] — si el número $A es mayor que 10.
  • Combinación de condiciones: [[ -d "$DIR" && -w "$DIR" ]].

Bucle: for, while y for aritmético

for sobre lista de archivos

for file in *.log; do
  gzip "$file"
done

for por rango

for i in {1..5}; do
  echo "Iteración $i"
done

For aritmético for ((…))

for ((i=0; i<10; i++)); do
  printf "%02d " "$i"
done
echo

while — leer un archivo línea por línea

while IFS= read -r line; do
  echo "-> $line"
done < data.txt

Funciones: reutiliza código

Sintaxis

greet() {
  local user=$1       # variable local
  echo "¡Hola, $user!"
}
greet "Olga"

Devolver estado y valores

is_port_open() {
  nc -z localhost "$1"
  return $?
}

if is_port_open 22; then
  echo "Acceso SSH disponible"
fi

Arrays y arrays asociativos

Arrays normales

servers=(web01 web02 db01)
for host in "${servers[@]}"; do
  ping -c1 "$host"
done

Arrays asociativos

declare -A ports=(
  [ssh]=22
  [http]=80
  [db]=5432
)
for service in "${!ports[@]}"; do
  echo "$service -> ${ports[$service]}"
done

Manejo de argumentos del script

Parámetros posicionales

#!/usr/bin/env bash
SRC=$1
DST=$2
cp -r "$SRC" "$DST"

getopts — banderas y opciones

usage() { echo "Uso: $0 -s ruta_origen -d ruta_destino"; }

while getopts ":s:d:" opt; do
  case $opt in
    s) SRC=$OPTARG ;;
    d) DST=$OPTARG ;;
    *) usage; exit 1 ;;
  esac
done

[[ -z $SRC || -z $DST ]] && { usage; exit 1; }
cp -r "$SRC" "$DST"

Manejo de errores y traps con trap

Capturar la salida del script

cleanup() {
  echo "Finalizando. Eliminando archivos temporales..."
  rm -f /tmp/mytemp.*
}
trap cleanup EXIT

Ejemplo de modo estricto + registro

#!/usr/bin/env bash
set -euo pipefail
exec > >(tee -a "/var/log/myscript.log") 2>&1

Escenarios prácticos de automatización

Escenario 1. Copias de seguridad de directorios con limpieza

#!/usr/bin/env bash
set -euo pipefail
SRC="/var/www"
DST="/backups/$(date +%F)"
mkdir -p "$DST"
tar -czf "$DST/www.tgz" "$SRC"
find /backups -type f -mtime +7 -delete

Escenario 2. Redimensionado masivo de imágenes

#!/usr/bin/env bash
set -euo pipefail
QUALITY=85
for img in *.jpg; do
  convert "$img" -resize 1280x -quality $QUALITY "small_$img"
done

Escenario 3. Reconstrucción de contenedores Docker desde una lista

#!/usr/bin/env bash
images=(api frontend worker)
for image in "${images[@]}"; do
  docker build -t "myorg/$image:latest" "./$image"
done

Escenario 4. Envío de un informe de espacio libre a Telegram

#!/usr/bin/env bash
set -euo pipefail
TOKEN="YOUR_TELEGRAM_BOT_TOKEN"
CHAT_ID="123456"
USAGE=$(df -h / | awk 'NR==2 {print $(NF-1)}')
curl -s -X POST 
  "https://api.telegram.org/bot$TOKEN/sendMessage" 
  -d "chat_id=$CHAT_ID&text=Espacio ocupado: $USAGE"

Ejecución programada con cron

# editar el archivo de crontab
crontab -e

# ejecutar backup.sh cada día a las 02:30
30 2 * * * /usr/local/bin/backup.sh

Es cómodo comprobar la expresión en Crontab Guru.

Depuración y pruebas

Trazado

bash -x script.sh

Para una salida más detallada, defina PS4='+ $BASH_SOURCE:$LINENO ' antes de set -x.

Pruebas unitarias con

bats‑core — un framework útil para comprobar funciones de Bash.

Mejores prácticas e herramientas

Conclusión

Los scripts Bash convierten operaciones repetitivas en un formato de texto sencillo, fácil de leer, versionar y compartir con colegas. Usando variables, condiciones, bucles, funciones y arrays, se pueden describir flujos de trabajo completos — desde copias de seguridad hasta despliegues de contenedores — y conservarlos de forma comprensible.

El progreso en habilidad viene acompañado de ampliar las herramientas: perfilar scripts con la utilidad time, escribir pruebas modulares con bats, acelerar tareas en paralelo con xargs -P o GNU parallel. Cuantos más patrones y técnicas tenga a mano, más confianza tendrá para automatizar nuevas áreas de trabajo.

Enlaces útiles para seguir aprendiendo

Alt text