2017-10-21 53 views
1

J'ai 10 commandes d'exécuter en parallèle:Rappel basé sur l'état de sortie de la commande dans les scripts bash shell?

comdA & comdB & comdC & comdD 

...

Est-il possible d'exécuter un rappel si l'une de ces commandes renvoient un état de sortie autre que 0?

Si cela n'est pas possible avec bash. que diriez-vous de php? Puis-je

function exec_with_callback ($comd) { 

    shell_exec($comd); 
    callback(); 

} 

exec_with_callback("comdA"); 
exec_with_callback("comdB"); 
... 
but in parallel? 

Si non, quelle autre langue puis-je utiliser?

+1

https://stackoverflow.com/questions/9258387/bash-ampersand-operator – chiliNUT

Répondre

1

Vous pouvez exécuter vos commandes en boucle et enregistrer les process_ids en utilisant la variable shell $! qui vous donne l'ID de processus du dernier travail en arrière-plan. Attendez que tous vos processus se terminent en utilisant wait <PID> dans une boucle.

n=0 
for pid in ${pidarray[@]}; do 
    wait ${pid} 
    exit_status_array[$n]=$? 
    ((n+=1)) 
done 

maintenant en boucle à travers la exit_status_array et de rappel de la commande correspondante si l'état de sortie est autre que 0

n=0 
for s in ${exit_status_array[@]}; do 
    if [[ ${s} -ne 0 ]]; then 
    commands[$n] & #callback 
    fi 
    ((n+=1)) 
done 

Vous pouvez répéter le processus indéfiniment si vous voulez en utilisant cette logique et appeler une fonction, etc.

0

peut-être que vous pouvez utiliser ceci:

#!/bin/bash 

function check() { 
    $1 >/dev/null 2>&1 
    echo $? 
} 

command=("curl -sSL google.com" "echo 1" 'ping localhost -c 1' 'ls' 'false') 

for ((i=0;i<${#command[@]};i++)); do 
    echo "Command \"${command[$i]}\" returned value $(check "${command[$i]}")" 
    if (($(check "${command[$i]}") != 0)); then second=1; fi 
done 

if ((second == 1)); then 
    echo "I must run second group of commands because something have not worked!" 
    echo 2 
else 
    echo "All is gone without issues! Goodbye $USER!" 
    exit 0 
fi 

vérifier la fonction exécuter la commande et retourner l'état de sortie, les commandes sont dans le tableau de commande et avec la boucle for nous pouvons voir toutes les commandes exécutées et leur statut de sortie. Si quelqu'un a un statut de sortie différent de zéro, une variable nous aide à lancer une commande if si toutes les commandes sont terminées avec d'autres commandes.

Exemple de sortie

[email protected]:~/Scrivania$ bash example 
Command "curl -sSL google.com" returned value 0 
Command "echo 1" returned value 0 
Command "ping localhost -c 1" returned value 0 
Command "ls" returned value 0 
Command "false" returned value 1 
I must run second group of commands because something have not worked! 
2 
[email protected]:~/Scrivania$ bash example 
Command "curl -sSL google.com" returned value 0 
Command "echo 1" returned value 0 
Command "ping localhost -c 1" returned value 0 
Command "ls" returned value 0 
Command "true" returned value 0 
All is gone without issues! Goodbye darby! 
[email protected]:~/Scrivania$ 
0

préparer un fichier myCommands contenant une commande par ligne:

echo "curl -sSL google.com" > myCommands.txt 
echo "echo 1"    >> myCommands.txt 
echo "ping localhost -c 1" >> myCommands.txt 
echo "ls"     >> myCommands.txt 
echo "false"    >> myCommands.txt 

et ensuite utiliser xargs, et vérifier le code de retour de xargs.

xargs --arg-file myCommands.txt --max-procs 5 -I COMMAND sh -c "COMMAND" 
[ $? -eq 0 ] && echo "All command have sucessfully finish with retrun code 0" && echo "You need check the result" 

Si le retour de code égal à 0 ==> toutes les commandes dans le fichier myCommands ont fini avec le code sucessfully retour 0

--max-procs: Exécuter jusqu'à processus max-procs à la fois; la valeur par défaut est 1. Si max-procs vaut 0, xargs exécute autant de processus que possible à la fois.