Comment continuer l’exécution du processus d’arrière-plan dans ce scénario

J’ai 3 processus a.sh, b.sh, c.sh qui sont exécutés en arrière-plan.

./a.sh & pid_a=$! ./b.sh & pid_b=$! ./c.sh & pid_c=$! 

Je dois m’assurer que les trois processus fonctionnent jusqu’au plus long processus. Si c.sh prend 10 secondes, a.sh prend 3 secondes, b.sh prend 5 secondes pour les temps d’exécution individuels, je dois exécuter a.sh, b.sh à nouveau pour m’assurer qu’ils existent jusqu’à la fin de c.sh.

J’essayais cette approche qui ne fonctionne certainement pas dans le scénario ci-dessus

  ./a.sh & while ps -p $! > /dev/null; do ./b.sh & pid_b=$! ./c.sh & pid_c=$! wait $pid_c done 

Comment puis-je l’obtenir?

Vous pouvez utiliser des fichiers temporaires comme indicateurs pour indiquer la fin de chaque processus pour la première fois. Exécutez chaque script dans une boucle d’arrière-plan jusqu’à ce que chacun des deux autres soit terminé au moins une fois.

 flag_dir=$(mktemp -d flagsXXXXX) flag_a=$flag_dir/a flag_b=$flag_dir/b flag_c=$flag_dir/c ( until [[ -f $flag_b && -f $flag_c ]]; do ./a.sh; touch $flag_a; done; ) & ( until [[ -f $flag_a && -f $flag_c ]]; do ./b.sh; touch $flag_b; done; ) & ( until [[ -f $flag_a && -f $flag_b ]]; do ./c.sh; touch $flag_c; done; ) & # Each until-loop runs until it sees the other two have completed at least one # cycle. Wait here until each loop finishes. wait # Clean up rm -rf "$flag_dir" 

[ Remarque Cela fonctionne uniquement pour bash. ksh93 kill se comporte différemment.]

Tant qu’il y a au moins un processus que vous êtes autorisé à tuer, kill -0 renverra le succès. Ajustez l’intervalle selon vos besoins.

 #! /bin/bash interval=1 pids= && for t in 2 3; do (sleep $t && echo slept $t seconds) & pids=${pids:+$pids }$! done while (kill -0 $pids) 2>& -; do sleep $interval # optional reporting: for pid in $pids; do (kill -0 $pid) 2>&- && echo $pid is alive done done 

Résulte en:

 6463 is alive 6464 is alive slept 2 seconds [1]- Done eval sleeper $t 6464 is alive slept 3 seconds [2]+ Done eval sleeper $t 

La suppression intégrée n’est pas cohérente en ce qui concerne les erreurs:

 $ ksh -c 'kill -0 571 6133 && echo ok || echo no' kill: 571: permission denied no $ bash -c 'kill -0 571 6133 && echo ok || echo no' bash: line 0: kill: (571) - Operation not permitted ok 

Tout d’abord, vous pouvez utiliser kill -0 pour tester le statut du processus pour c.sh , plutôt que d’utiliser wait pour attendre qu’il se termine.

Deuxièmement, vous pouvez utiliser deux processus distincts pour surveiller l’état des scripts a.sh et b.sh

Troisièmement, cela suppose que c.sh est le processus le plus long.

Ainsi, le processus de surveillance 1 effectue les opérations suivantes:

 # I have pid_c ./a.sh & pid_a=$! while wait $pid_a; do if kill -0 $pid_c; then ./a.sh& pid_a=$! fi done 

et surveillez le processus 2:

 # I have pid_c ./b.sh & pid_b=$! while wait $pid_b; do if kill -0 $pid_c; then ./b.sh & pid_b=$! fi done 

Ainsi, vous surveillez les 2 processus séparément. Cependant, si vous devez également les surveiller, lancez les moniteurs comme 2 tâches en arrière-plan et une simple wait attendra sur c.sh ainsi que sur les 2 moniteurs.

Remarque: kill -0 $PID renvoie 0 si $PID est en cours d’exécution ou 1 si $PID est terminé.