web-dev-qa-db-fra.com

Appeler plusieurs scripts bash et les exécuter en parallèle, pas dans l'ordre

Supposons que j'ai trois (ou plus) scripts bash: script1.sh, script2.sh, et script3.sh. Je voudrais appeler ces trois scripts et les exécuter dans parallèle. Pour ce faire, vous pouvez simplement exécuter les commandes suivantes:

Nohup bash script1.sh &
Nohup bash script2.sh &
Nohup bash script3.sh &

(En général, les scripts peuvent prendre plusieurs heures ou jours pour se terminer, donc je voudrais utiliser Nohup pour qu'ils continuent de fonctionner même si ma console se ferme.)

Mais, existe-t-il un moyen d'exécuter ces trois commandes en parallèle avec un appel nique?

Je pensais à quelque chose comme

Nohup bash script{1..3}.sh &

mais cela semble exécuter script1.sh, script2.sh, et script3.sh en séquence, pas en parallèle.

20
Andrew
for((i=1;i<100;i++)); do Nohup bash script${i}.sh & done
15
Hauke Laging

Une meilleure façon serait d'utiliser GNU Parallel . GNU parallel est simple et avec lui nous pouvons contrôler le nombre de jobs à exécuter en parallèle avec plus de contrôle sur les jobs.

Dans la commande ci-dessous, script{1..3}.sh Est développé et envoyé en tant qu'arguments à bash en parallèle. Ici, -j0 Indique qu'il faut exécuter autant de travaux que possible. Par défaut, parallel exécute un travail pour un cœur de processeur.

$ parallel -j0 bash :::: <(ls script{1..3}.sh)

Et vous pouvez également essayer d'utiliser

$ parallel -j0 bash ::: script{1..3}.sh

Lors de l'exécution de la deuxième méthode si vous obtenez un message d'erreur, cela signifie que l'option --tollef Est définie dans /etc/parallel/config Et que cela doit être supprimé et tout fonctionnera correctement.

Vous pouvez lire la page de manuel de GNU Parallelsici pour des options plus riches.

Et si vous exécutez les travaux à partir d'une machine distante, mieux vaut utiliser screen afin que la session ne soit pas fermée en raison de problèmes de réseau. Nohup n'est pas nécessaire, car les versions récentes de bash viennent avec huponexit comme off et cela empêchera le shell parent d'envoyer un signal HUP à ses enfants pendant sa sortie. Dans le cas où ce n'est pas mal réglé, faites-le avec

$ shopt -u huponexit  
14
Kannan Mohan

Nous pouvons également utiliser xargs pour exécuter plusieurs scripts en parallèle.

$ ls script{1..5}.sh|xargs -n 1 -P 0 bash

ici, chaque script est passé à bash comme argument séparément. -P 0 indique que le nombre de processus parallèles peut être autant que possible. Il est également plus sûr d'utiliser bash par défaut job control feature(&).

9
Yaalie

Une seule solution ligne:

$ Nohup bash script1.sh & Nohup bash script2.sh & Nohup bash script3.sh &

Moins facétieusement, utilisez simplement un script wrapper:

$ cat script.sh
#!/usr/bin/env bash
script1.sh &
script2.sh &
script3.sh &
$ Nohup script.sh &

Ou passez en boucle dessus:

for script in dir/*.sh
do
    Nohup bash "$script" &
done
5
l0b0

Si vous cherchez à vous épargner quelques efforts de frappe

eval "Nohup bash "script{1..3}.sh" &"

Ou à y réfléchir, peut-être pas

2
iruvar

Découvrez cet outil: https://github.com/wagoodman/bashful

Dites que vous avez mytasks.yaml avec

tasks:
    - name: A title for some tasks
      parallel-tasks:
        - cmd: ./script1.sh
        - cmd: ./script2.sh -x an-arg
        - cmd: ./script3.sh -y some-other-arg

Et vous le faites comme ça:

Nohup bashful run mytasks.yaml

Vos scripts seraient exécutés en parallèle avec une barre de progression verticale (+ eta si vous l'avez déjà exécuté et que l'heure est déterministe). Vous pouvez modifier le nombre de tâches que vous souhaitez exécuter en parallèle si vous commencez à exécuter plus que les 3 données ici:

config:
    max-parallel-commands: 6
tasks:
    ...

Avertissement: je suis l'auteur.

1
wagoodman

Utilisez Parallelshell

parallelshell "echo 1" "echo 2" "echo 3"

https://github.com/keithamus/parallelshell

0
rofrol

Je propose un utilitaire beaucoup plus simple que je viens d'écrire. Il est actuellement appelé par, mais sera renommé bientôt en parl ou en pll, pas encore décidé.

https://github.com/k-bx/par

L'API est aussi simple que:

par "script1.sh" "script2.sh" "script3.sh"
0