Cómo crear colas de comandos concurrentes en Bash con xargs y mkfifo
Concurrent Shell Command Queues

El autor comparte una implementación de una cola de comandos en Bash que permite ejecutar comandos en paralelo con un límite de concurrencia, usando xargs -P y un FIFO. Incluye funciones para iniciar la cola, enviar comandos y esperar a que se vacíe, con ejemplos de uso y advertencias sobre sus limitaciones. Aunque reconoce que otros lenguajes como Python son más adecuados, lo hace por su afición a Bash y como reto personal.
La respuesta es: sí, pero requiere algo de trabajo para ser semiresiliente y portátil.
- js2
> Cómo ejecutar comandos de shell en paralelo mientras se limita su concurrencia.
Dependiendo de la tarea, genera un Makefile y ejecútalo con:
make -j <concurrency>
> Mi caso de uso original tenía que ver con hacer una gran cantidad de solicitudes web
De hecho, este es el caso de uso que me llevó a pensar en usar un Makefile para concurrencia hace probablemente 20 años. Una regla para descargar cada URL a un archivo. Luego un simple `make -j <jobs>` con la concurrencia que deseara y de bonus: omitir automáticamente los archivos ya descargados. Por ejemplo:
BASE := https://example.com/files
FILES := a.txt b.txt c.txt d.txt e.txt
.DELETE_ON_ERROR:
all: $(FILES)
$(FILES):
curl -sS --fail --max-time 30 -o $@ $(BASE)/$@
O, para emular uno de los ejemplos del blog post:
SHELL := bash
.SHELLFLAGS := -o pipefail -c
N := 1 2 3 4 5
REQS := $(N:%=req-%)
.PHONY: all $(REQS)
all: $(REQS)
$(REQS): req-%:
@curl -sS --fail-with-body --max-time 10 -X POST -H 'Content-Type: application/json' \
-d '{"request": $*}' https://postman-echo.com/post | jq -c .json
Ejecutar con:
$ make -O -j 3
> No necesitas conocer todos los comandos que quieres ejecutar de antemano, puedes enviar comandos a lo largo del tiempo.
Ah, sí, eso pone a Make en el mismo saco que `xargs -P` / GNU `parallel` y requiere algo más ingenioso.
- reconquestio
También está sem de GNU Parallel: https://www.gnu.org/software/parallel/sem.html
sem --id jobs -j 2 'sleep 1; echo FIRST'
sem --id jobs -j 2 'echo SECOND'
sem --id jobs -j 2 'echo THIRD'
sem --id jobs --wait
SECOND
THIRD
FIRST
- 0cf8612b2e1e
Me gusta mucho pueue para esto. Como un slurm o parallel ligero pero sin el molesto aviso de citación.