web-dev-qa-db-fra.com

Script Bash traitant un nombre limité de commandes en parallèle

J'ai un script bash qui ressemble à ceci:

#!/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

Mais traiter chaque ligne jusqu'à la fin de la commande, puis passer à la suivante prend beaucoup de temps. Je souhaite traiter par exemple 20 lignes à la fois, puis quand elles sont terminées, 20 autres lignes sont traitées.

J'ai pensé à wget LINK1 >/dev/null 2>&1 & envoyer la commande à l'arrière-plan et continuer, mais il y a 4000 lignes ici, cela signifie que j'aurai des problèmes de performances, sans parler du nombre limité de processus à démarrer en même temps, donc Ce n'est pas une bonne idée.

Une solution à laquelle je pense en ce moment consiste à vérifier si l’une des commandes est toujours en cours d’exécution. Par exemple, après 20 lignes, je peux ajouter cette boucle:

while [  $(ps -ef | grep KEYWORD | grep -v grep | wc -l) -gt 0 ]; do
sleep 1
done

Bien sûr, dans ce cas, je devrai ajouter & au bout de la ligne! Mais je pense que ce n'est pas la bonne façon de le faire.

Alors, comment puis-je regrouper chacune des 20 lignes et attendre qu’elles se terminent avant de passer aux 20 lignes suivantes, ce script est généré de manière dynamique afin que je puisse faire les calculs que je veux pendant la génération, mais il n’EST PAS nécessaire utilisez wget, c’était juste un exemple, donc toute solution spécifique à wget ne me servira à rien.

180
AL-Kateb

Utilisez le wait intégré:

process1 &
process2 &
process3 &
process4 &
wait
process5 &
process6 &
process7 &
process8 &
wait

Pour l'exemple ci-dessus, 4 processus process1 ... process4 seront démarrés en arrière-plan et le Shell attendra qu'ils soient terminés avant de démarrer le prochain jeu.

Depuis le manuel GN :

wait [jobspec or pid ...]

Attendez que le processus enfant spécifié par chaque ID de processus pid ou jobpec, spécification de travail, quitte et renvoie le statut de sortie de la dernière commande attendue. Si une spécification de travail est donnée, tous les processus du travail sont attendus. Si aucun argument n'est fourni, tous les processus enfants actuellement actifs sont attendus et le statut de retour est zéro. Si ni jobspec ni pid ne spécifient un processus enfant actif du shell, le statut de retour est 127.

315
devnull

Voir parallèle . Sa syntaxe est similaire à xargs, mais il exécute les commandes en parallèle.

90
choroba

En fait, xargscan exécute des commandes en parallèle pour vous. Il existe une option spéciale de ligne de commande -P max_procs pour cela. Voir man xargs.

61
Vader B

Vous pouvez exécuter 20 processus et utiliser la commande:

wait

Votre script attendra et continuera lorsque tous vos travaux en arrière-plan seront terminés.

7
Binpix