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 (
grep,awk,sed,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:
- El archivo comienza con la línea shebang
#!/usr/bin/env bash. - El archivo tiene permiso de ejecución:
chmod +x myscript.sh. - Se puede ejecutar de dos maneras:
bash myscript.sho./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$Aes 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
- ShellCheck — análisis estático de código ( versión en línea).
- explainshell — explicación línea por línea de comandos ( servicio).
- devhints/bash — chuleta útil ( devhints.io/bash).
- GitHub Actions — ejecutar scripts Bash en CI ( documentación).
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.