Je veux faire les choses suivantes:
exécuter plusieurs scripts shell (ici 2 scripts) simultanément. p> li>
Attendez que les deux scripts finissent p> li>
Valeur de décharge de chaque script p> li> ul>
Cependant, main.sh code> ne fonctionne pas comme prévu. p>
main.sh h2>
A. / H2>
#!/bin/bash
sleep 5
echo 2
5 Réponses :
La réponse que vous recherchez est dans cette question shell - obtenez le code de sortie de l'arrière-plan Processus
Fondamentalement, lorsque vous vous appuyez sur un processus, vous ne pouvez pas obtenir son code de sortie directement. Mais si vous exécutez la commande BASH WAIT, alors ceci fonctionnera Même si A.Sh se termine avant de courir attendre. La variable spéciale weatt code> s de sortie de sortie renvoie le code de sortie du processus d'arrière-plan. P>
$? Code> détient le code de sortie du processus précédent. Et
$! Code> contient l'ID de processus du processus précédemment exécuté. P> p>
Cela ne mettra pas la valeur de retour d'attente dans RET1, mais définira toujours RET1 sur la chaîne vide. (attendre n'écrire rien à stdout)
Voici quelques codes que j'ai couru, cela semble faire exactement ce que vous voulez. Juste insérer Notez que cela capture l'état de la sortie de la script et non ce qu'il génère sur ./ a.sh code> et
./ b.sh code> le cas échéant:
stdout code>. Il n'y a pas de moyen simple de capturer le
stdout code> d'un script en cours d'exécution dans l'arrière-plan, je vous conseillerais de vous conseiller d'utiliser le Statut de sortie pour renvoyer des informations au processus d'appel. P> p>
Les backtsticks ne donnent pas la valeur renvoyée par la commande, mais la sortie de la commande. Pour obtenir les valeurs de retour:
#!/bin/sh ./a.sh & ./b.sh ret2=$? # get value returned by b.sh wait %1 # Wait for a.sh to finish ret1=$? # get value returned by a.sh echo "$ret1: $ret2"
Remarque: ce qui précède fonctionne dans Bash, mais je ne suis pas certain de la portabilité de% 1. Vous devrez peut-être utiliser "attendre $!" au lieu.
+1 pour GNU parallèle. Au début, j'ai essayé d'utiliser attendre code> comme suggéré par Lee Netherton et d'autres. Et je me suis immédiatement retrouvé à réfléchir à comment écrire du code pour collecter des statuts de sortie dans une liste, boucle sur eux, etc. GNU parallèle prend soin de tout ce merde logistique :) Dès la sortie de la boîte. C'était aussi simple que
trouver. -Name * .sh | parallèle -j0 sh {} code>
Si vous avez Bash 4.2 ou ultérieur disponible, les éléments suivants vous seront utiles. Il utilise des tableaux associatifs pour stocker des noms de tâches et leur "code" ainsi que des noms de tâches et de leurs PID. J'ai également construit dans une simple méthode de limitation de taux qui pourrait être pratique si vos tâches consomment beaucoup de processeur ou d'E / S et que vous souhaitez limiter le nombre de tâches simultanées.
Le script lance toutes les tâches dans la première Boucle et consomme les résultats dans le second. P>
Ceci est un peu surpeuplé pour des cas simples, mais cela permet de jolies choses soignées. Par exemple, on peut stocker des messages d'erreur pour chaque tâche dans un autre tableau associatif et les imprimer après que tout s'est installé. P>
(J'ai copié cette réponse sur ma réponse Ici parce que cela résout les deux questions, si ce n'est pas ok, veuillez me le dire ou le remplacer directement par un lien ou tout ce qui est approprié.) P>
#! /bin/bash main () { local -A pids=() local -A tasks=([task1]="echo 1" [task2]="echo 2" [task3]="echo 3" [task4]="false" [task5]="echo 5" [task6]="false") local max_concurrent_tasks=2 for key in "${!tasks[@]}"; do while [ $(jobs 2>&1 | grep -c Running) -ge "$max_concurrent_tasks" ]; do sleep 1 # gnu sleep allows floating point here... done ${tasks[$key]} & pids+=(["$key"]="$!") done errors=0 for key in "${!tasks[@]}"; do pid=${pids[$key]} local cur_ret=0 if [ -z "$pid" ]; then echo "No Job ID known for the $key process" # should never happen cur_ret=1 else wait $pid cur_ret=$? fi if [ "$cur_ret" -ne 0 ]; then errors=$(($errors + 1)) echo "$key (${tasks[$key]}) failed." fi done return $errors } main
Bonjour, désolé d'avoir sauté tard, mais je veux capturer l'heure de début du temps de démarrage et le temps écoulé pour chaque tâche individuelle terminée / incomplète. Mais je suis incapable de le faire
Vous pouvez ajouter un autre tableau similaire à PIDS CODE> et stocker le temps de départ de là, mais il nécessiterait un style différent d'attente des processus. Enotime pour comprendre quelque chose, peut-être créer une nouvelle question pourrait être meilleure quand même?
Salut Just Besoin d'une clarification Pouvez-vous expliquer ces emplois de ligne 2> & 1 Comment ça ne reçoive-t-il que les emplois m'exécutent actuellement? Que se passera-t-il si d'autres emplois fonctionnent également qui ne sont pas déclenchés par moi (utilisateur)
Emplois CODE> Imprime uniquement les travaux Shell de la coque actuelle. Il n'inclut pas les travaux d'autres coquilles / terminaux ou même d'autres utilisateurs. Toutefois, si vous démarrez un travail d'arrière-plan avant d'exécuter un script à l'aide du code ci-dessus, ce travail serait également renvoyé et fera partie du nombre d'emplois «en cours d'exécution». Cela pourrait ou pourrait ne pas être recherché mais je suppose qu'il est logique de l'inclure dans la plupart des cas. Sinon, il faudrait enregistrer les travaux qui existent lorsque le script est démarré et les filtre pour le calcul.
Jetez un coup d'œil à Stackoverflow.com/questions/356100/...