2017-02-01 1 views
0

J'ai une boucle for et je veux la traiter 4 fois en parallèle à la fois. J'ai essayé le code suivant de la page https://unix.stackexchange.com/questions/103920/parallelize-a-bash-for-loop:Exécutions parallèles dans les lots N-process dans BASH

task(){ 
sleep 0.5; echo "$1"; 
} 
N=4 
(
for thing in a b c d e f g; do 
    ((i=i%N)); ((i++==0)) && wait 
    task "$thing" & 
done 
) 

J'ai stocké le fichier ci-dessus test.sh, la sortie, je l'obtiens est la suivante:

path$ ./test.sh 
a 
b 
c 
d 
path$ e 
f 
g 

et le curseur n » t revenir à mon terminal après 'g', il attend/dort indéfiniment.Je veux que le curseur revienne à mon terminal et aussi je ne comprends pas pourquoi la sortie 'e' a mon chemin qui le précède, ne devrait pas la sortie être affiché comme 'a' à 'g' en continu et le code devrait s'arrêter?

+0

Votre code fera les 7 choses dans la boucle juste une fois, parce que la boucle est pas dans une autre boucle. Pourtant, vous dites que vous voulez traiter la boucle 4 fois? Alors, y a-t-il vraiment 28 choses à traiter? –

+0

Quelle devrait être la commande globale? a, b, c & d courent tous en parallèle jusqu'à ce que tout ait fini, alors e, f, g & a courent tous en parallèle jusqu'à ce qu'ils finissent tous peut-être? –

+0

oui @MarkSetchell Je veux faire un, b, c & d tous courir en parallèle jusqu'à ce que tous ont fini, puis e, f, g & a tous courir en parallèle jusqu'à ce qu'ils finissent tous – pku

Répondre

0

Si vous appuyez sur enter, le jouet peut voir que vous êtes dans un shell normal. Si vous voulez attendre processus batched avant la sortie du script vient ajouter wait à la fin du scénario

+0

Merci, mais je ne comprends pas pourquoi ai-je besoin appuyer sur Entrée pour revenir au shell normal au lieu de revenir par lui-même à la fin du code. En outre, pourriez-vous élaborer sur "Si vous voulez attendre le processus par lots avant de quitter le script, ajoutez simplement wait à la fin du script" – pku

+0

Vous voyez l'invite 'chemin $' - cela signifie que le script est terminé. Et vous êtes en coquille. 'wait' est une commande bash qui attend que tout soit exécuté dans le processus d'arrière-plan du shell en cours. –

+0

alors quand je vois la ligne 'chemin $ e' le code est terminé mais c'est juste imprimer des choses avec un retard? – pku

2

Il est assez difficile de comprendre ce que vous voulez, mais je pense que vous voulez faire 7 choses, appelé a, b, c .. g en parallèle, pas plus de 4 à la fois.

Si oui, vous pouvez essayer ceci:

echo {a..g} | xargs -P4 -n1 bash -c 'echo "$1"; sleep 2}' {} 

qui envoie les lettres a .. g dans xargs qui commence alors une nouvelle coquille bash pour chaque lettre, en passant une lettre (-n1) à la coquille comme {}. Le shell bash sélectionne le paramètre (son premier paramètre étant $1) et l'échoue puis attend 2 secondes avant de quitter - pour que vous puissiez voir la pause. Le -P4 indique à xargs d'exécuter 4 instances de bash à la fois en parallèle.

Voici une petite vidéo en cours d'exécution. La première utilise -P4 et fonctionne en groupes de 4, la deuxième séquence utilise -P2 et fait 2 à la fois:

enter image description here


Ou, plus simplement, si vous ne me dérange pas les dépenses de 10 secondes l'installation de GNU parallèle:

parallel -j4 -k 'echo {}; sleep 2' ::: {a..g} 
+0

Merci pour la solution mais je voudrais vraiment que vous puissiez éditer mon code ci-dessus au lieu de donner une ligne de commande car une solution de ligne de commande est possible dans ce cas mais en réalité ma tâche() va avoir beaucoup plus de choses à traiter que simplement faire écho à la variable – pku

+0

Faites simplement 'export -f task' pour exporter votre' task() ', puis faites' parallel ... task' –