Curso de Shell Scripting
Cuando los scripts deben procesar grandes cantidades de datos o archivos, hacerlo de forma secuencial puede ser muy lento. Bash ofrece varias formas de ejecutar tareas en paralelo y optimizar los pipelines.
16.1. Problemas comunes en scripts lentos
- Procesar miles de archivos uno por uno en un bucle.
- Repetir tareas que podrían hacerse en paralelo.
- Usar pipelines ineficientes con muchas etapas innecesarias.
- Lanzar procesos externos dentro de bucles (
for,while) sin necesidad.
👉 Objetivo: minimizar procesos y aprovechar la paralelización.
16.2. Ejecutar tareas en segundo plano con &
Se puede paralelizar fácilmente ejecutando comandos en background.
1#!/usr/bin/env bash 2 3echo "Procesando tareas..." 4sleep 3 & 5sleep 2 & 6sleep 1 & 7 8wait # espera a que terminen todos 9echo "Tareas finalizadas"
Salida (tiempo total ≈ 3 s en vez de 6 s):
Procesando tareas...
Tareas finalizadas
16.3. Paralelismo controlado con xargs -P
xargs permite pasar una lista de elementos a un comando.
La opción -P indica cuántos procesos ejecutar en paralelo.
Ejemplo: convertir imágenes a PNG en paralelo:
1ls *.jpg | xargs -n1 -P4 convert -resize 800x800 {} {.}.png
-n1→ pasa 1 argumento cada vez-P4→ ejecuta 4 tareas en paralelo{}→ representa el archivo de entrada{.}→ nombre sin extensión
▸ Ejemplo simple: dormir en paralelo
1seq 1 5 | xargs -n1 -P3 bash -c 'echo "Procesando $1"; sleep $1' _
👉 Ejecuta 3 tareas en paralelo en lugar de una por una.
16.4. GNU parallel
Herramienta más potente y flexible que xargs.
(A veces no viene instalada por defecto).
Instalación en Ubuntu/Debian:
1sudo apt install parallel
Ejemplo: redimensionar imágenes en paralelo:
1parallel convert {} {.}.png ::: *.jpg
:::→ separa el comando de la lista de argumentos.
▸ Controlar número de trabajos
1parallel -j 4 gzip {} ::: *.log
👉 Comprime archivos .log usando 4 procesos en paralelo.
▸ Pipeline con parallel
Ejemplo: procesar lista de URLs:
1cat urls.txt | parallel -j 5 "curl -s {} -o {#}.html"
-j 5→ 5 descargas simultáneas{#}→ índice del trabajo en ejecución
16.5. Sustitución de procesos <() y >()
Permite usar la salida de un comando como si fuera un archivo temporal, sin escribir al disco.
1diff <(sort archivo1.txt) <(sort archivo2.txt)
👉 Compara dos archivos ordenados al vuelo, sin archivos intermedios.
16.6. Optimizar pipelines
Cada | lanza un proceso adicional.
Minimiza etapas innecesarias.
Ejemplo ineficiente:
1cat archivo.txt | grep "ERROR" | sort | uniq -c
Ejemplo optimizado:
1grep "ERROR" archivo.txt | sort | uniq -c
👉 Evitamos el uso innecesario de cat.
16.7. Medir el tiempo de ejecución
Puedes medir el tiempo total para evaluar mejoras:
1time ./mi_script.sh
O con el comando incorporado en scripts:
1START=$(date +%s) 2# ... código ... 3END=$(date +%s) 4echo "Tiempo total: $((END-START)) segundos"
16.8. Ejemplo integrador: procesamiento masivo de logs
Supón que tienes miles de archivos .log y quieres contar cuántas líneas con “ERROR” tiene cada uno y guardar el resultado en archivos separados.
1#!/usr/bin/env bash 2set -Eeuo pipefail 3 4mkdir -p resultados 5 6ls *.log | xargs -n1 -P4 bash -c ' 7 archivo="$1" 8 grep -c "ERROR" "$archivo" > "resultados/${archivo%.log}_errores.txt" 9' _
👉 Procesa los logs en paralelo con 4 procesos simultáneos.
🏋️♂️ Ejercicio práctico 1
Crea un script procesa_urls.sh que:
- Lea una lista de URLs de
urls.txt. - Descargue cada página usando
curl -s -o pagina_X.html. - Use
xargs -P4oparallelpara hacer varias descargas al mismo tiempo. - Muestre el tiempo total de ejecución.
🏋️♂️ Ejercicio práctico 2
Crea un script compara_archivos.sh que:
- Compare pares de archivos listados en
pares.txt(formato:archivo1 archivo2por línea). - Use
diffcon sustitución de procesos<()para comparar los archivos ordenados. - Haga las comparaciones en paralelo con
xargs -P2.
🏋️♂️ Ejercicio práctico 3
Crea un script comprime_logs.sh que:
- Encuentre todos los archivos
.logde más de 5 MB. - Los comprima en paralelo usando
parallel -j 4 gzip {}. - Muestre cuánto tiempo tardó todo el proceso.
✅ Buenas prácticas
- ✅ Paraleliza solo si las tareas son independientes entre sí.
- ✅ Ajusta el número de procesos (
-Po-j) según los núcleos de la CPU. - ✅ Usa sustitución de procesos para evitar archivos temporales.
- ✅ Optimiza los pipelines quitando comandos innecesarios.
- ✅ Mide el tiempo antes y después para comprobar mejoras reales.
- Loading...