198 votes

<script Bash en traitement d'un nombre limité de commandes en parallèle <script>

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'à ce que la commande soit terminée puis passer à la suivante est très chronophage, je veux traiter par exemple 20 lignes à la fois puis quand elles sont terminées, traiter 20 autres lignes.

J'ai pensé à wget LINK1 >/dev/null 2>&1 & pour envoyer la commande en arrière-plan et continuer, mais il y a 4000 lignes ici cela signifie que je vais rencontrer des problèmes de performance, sans parler du fait que je serai limité en termes de combien de processus je devrais démarrer en même temps, donc ce n'est pas une bonne idée.

Une solution à laquelle je pense actuellement est de vérifier si l'une des commandes est encore en cours d'exécution ou non, par exemple après 20 lignes je peux ajouter cette boucle :

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

Évidemment, dans ce cas, je devrai ajouter & à la fin de la ligne ! Mais j'ai le sentiment que ce n'est pas la bonne manière de le faire.

Alors comment regrouper réellement chaque 20 lignes ensemble et attendre qu'elles terminent avant de passer aux 20 lignes suivantes, ce script est généré de manière dynamique donc je peux faire tout le calcul que je veux dessus pendant son génération, mais il N'A PAS besoin d'utiliser wget, c'était juste un exemple donc toute solution spécifique à wget ne me sera d'aucune utilité.

332voto

devnull Points 45016

Utilisez le wait intégré :

processus1 &
processus2 &
processus3 &
processus4 &
wait
processus5 &
processus6 &
processus7 &
processus8 &
wait

Pour l'exemple ci-dessus, 4 processus processus1 ... processus4 seraient lancés en arrière-plan et le shell attendrait qu'ils soient terminés avant de démarrer le prochain ensemble.

Depuis le manuel GNU:

wait [numéro de tâche ou pid ...]

Attendre que le processus enfant spécifié par chaque PID de processus ou la spécification de tâche jobspec se termine et renvoyer le code de sortie de la dernière commande pour laquelle on attendait. Si une spécification de tâche est donnée, tous les processus de la tâche sont attendus. Si aucun argument n'est donné, tous les processus enfants actifs en cours sont attendus et le code de sortie est zéro. Si ni jobspec ni pid ne spécifient un processus enfant actif du shell, le code de sortie est 127.

97voto

choroba Points 56333

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

73voto

Vader B Points 831

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

7voto

Binpix Points 79

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

attendre

Votre script attendra et continuera une fois que tous vos tâches en arrière-plan seront terminées.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X