Tengo un script bash que se ve así:
#!/bin/bash
wget LINK1 >/dev/null 2>&1
wget LINK2 >/dev/null 2>&1
wget LINK3 >/dev/null 2>&1
wget LINK4 >/dev/null 2>&1
# ..
# ..
wget LINK4000 >/dev/null 2>&1
Pero procesar cada línea hasta que finalice el comando y luego pasar a la siguiente lleva mucho tiempo, quiero procesar, por ejemplo, 20 líneas a la vez y luego, cuando están terminadas, se procesan otras 20 líneas.
Pensé wget LINK1 >/dev/null 2>&1 &
en enviar el comando a un segundo plano y continuar, pero hay 4000 líneas aquí, lo que significa que tendré problemas de rendimiento, sin mencionar la limitación en la cantidad de procesos que debo iniciar al mismo tiempo, por lo que no es un buen idea.
Una solución en la que estoy pensando ahora es verificar si uno de los comandos aún se está ejecutando o no, por ejemplo, después de 20 líneas puedo agregar este bucle:
while [ $(ps -ef | grep KEYWORD | grep -v grep | wc -l) -gt 0 ]; do
sleep 1
done
¡Por supuesto que en este caso tendré que agregar y al final de la línea! Pero siento que esta no es la forma correcta de hacerlo.
Entonces, ¿cómo puedo agrupar cada una de las 20 líneas y esperar a que terminen antes de pasar a las siguientes 20 líneas? use wget, fue solo un ejemplo, por lo que cualquier solución específica de wget no me servirá de nada.
wait
es la respuesta correcta aquí, perowhile [ $(ps …
sería mucho mejor escribirlowhile pkill -0 $KEYWORD…
usando proctools ... es decir, por razones legítimas para verificar si un proceso con un nombre específico aún se está ejecutando.Respuestas:
Use el
wait
incorporado:Para el ejemplo anterior, 4 procesos
process1
...process4
se iniciarían en segundo plano y el shell esperaría hasta que se completen antes de comenzar el siguiente conjunto.Del manual de GNU :
fuente
i=0; waitevery=4; for link in "${links[@]}"; do wget "$link" & (( i++%waitevery==0 )) && wait; done >/dev/null 2>&1
Ver paralelo . Su sintaxis es similar a
xargs
, pero ejecuta los comandos en paralelo.fuente
wait
, ya que se encarga de comenzar nuevos trabajos a medida que se completan los viejos, en lugar de esperar a que termine un lote completo antes de comenzar el siguiente.cat list_of_links.txt | parallel -j 4 wget {}
lo que mantendrá cuatrowget
s funcionando a la vez.parallel
.parallel --jobs 4 < list_of_commands.sh
, donde list_of_commands.sh es un archivo con un solo comando (por ejemplowget LINK1
, nota sin el&
) en cada línea. Puede que tenga que hacerCTRL+Z
ybg
después dejarlo ejecutándose en segundo plano.De hecho,
xargs
puede ejecutar comandos en paralelo para usted. Hay una-P max_procs
opción especial de línea de comandos para eso. Verman xargs
.fuente
Puede ejecutar 20 procesos y usar el comando:
Su secuencia de comandos esperará y continuará cuando finalicen todos sus trabajos en segundo plano.
fuente