j'ai un problème avec une variable dont la valeur est censé être modifié à la fin d'une fonction. En effet, voici à quoi ressemble ma fonction :
recherche_pid_en_direct_sans_duree( )
{
k=0
echo "waiting for end of process or sigterm"
while [[ $k -eq 0 && "$valeur_trap" == "off" ]]
do
if [ "$sarx_execute" == "yes" ]
then
if ! ps $1 > /dev/null
then
k=$(($k+1))
echo "the processus $1 has been stopped"
fi
fi
sleep 5
done
echo "sorti de la boucle du pid $1"
compteurfinal=$(($compteurfinal-1))
export compteurfinal
echo "compteurfinal de $1 = $compteurfinal"
killid $1
}
Ma fonction est censé bouclé à l'infini tant que l'ID en question ( $1 ) existe, et des qu'il disparait, sortir de la boucle, décrémenté la variable compteurfinal
Je fais ensuite appel à ma fonction comme cela :
if [ "$is_there_an_id" == "yes" ]
then
if [ "$duree_simulation" == "yes" ]
then
for i in "$pid" "$deuxieme_id" "$troisieme_id" "$quatrieme_id" "$cinquieme_id"
do
if [ ! $(echo $i | grep -v [a-zA-Z{}@_/\)\(:\"\'-] | wc -l) -eq 0 ]
then
recherche_pid_en_direct_avec_duree $i &
fi
done
else
for i in "$pid" "$deuxieme_id" "$troisieme_id" "$quatrieme_id" "$cinquieme_id"
do
if [ ! $(echo $i | grep -v [a-zA-Z{}@_/\)\(:\"\'-] | wc -l) -eq 0 ]
then
recherche_pid_en_direct_sans_duree $i &
fi
done
fi
while [ $compteurfinal != 0 ]
do
sleep 3
echo $compteurfinal
done
else
.................
Je lance donc un certain nombre de fois la fonction "recherche_pid_en_direct_sans_duree" ( en fonction du nb de param allant de 1 a 5 ) , puis je boucle tant que la valeur de compteurfinal n'est pas égale à 0.
Cependant, lorsque j'execute le code, voilà ce que j'obtiens :
./stat.sh 18790 18791
waiting for end of process or sigterm
waiting for end of process or sigterm
2
2
2
2
2
2
the processus 18790 has been stopped
2
2
sorti de la boucle du pid 18790
compteurfinal de 18790 = 1 #<==== bonne valeur !!
2 #<==== retour à la valeur d'origine ... ?
2
2
2
..
..
boucle infini
J'ai essayé avec et sans faire un export de cette variable, rien ne change.
Si vous avez une idée d'où cela peut provenir, je suis preneur...
Bonjour,
merci de ta réponse.
Je viens de me renseigner un peu sur wait $pid, et d'aprés ce que je pense avoir compris, ce qu'il faudrait faire, c'est en quelque sorte :
-rajouter une variable pour attraper l'ID de chaque lancement de
"recherche_pid_en_direct_sans_duree $i &" en faisant comme cela :
if [ ! $(echo $i | grep -v [a-zA-Z{}@_/\)\(:\"\'-] | wc -l) -eq 0 ]
then
recherche_pid_en_direct_sans_duree $i &
pid_[$i]=$! #attraper l'ID
fi
-et ensuite remplacer la boucle while [ $compteurfinal != 0 ] par une boucle du genre
for i in "$pid" "$deuxieme_id" "$troisieme_id" "$quatrieme_id" "$cinquieme_id"
do
if [ ! $(echo $i | grep -v [a-zA-Z{}@_/\)\(:\"\'-] | wc -l) -eq 0 ]
then
wait pid_[$i]
fi
done
sachant que si le 2eme ID se termine avant le 1er, cela n'a pas d'importance car on ne sort de la boucle que quand les 3 sont terminé?
J'avoue que je m'étais contenté de lire ton commentaire et les parties en gras :) Du coup j'ai dû lire ton code, et je m'aperçois que ta variable $pid ne contient en fait pas le pid.
Si j'ai bien compris, la fin des processus n'est pas du ressors de ton script. Il se contente d'attendre qu'ils se terminent.
En gros, toute ta première fonction peut être remplacée par le wait $pid (modulo tes tests de contenu de variable), une fois que tu as transformé le $i en $pid. Pour cela, tu peux jeter un oeil du côté de pidof. Il faut juste faire attention à ce que cette commande ne te renvoie pas plusieurs ID.
Du coup tu n'as plus besoin de faire ce polling horrible (while... sleep). Tu as juste à faire quelque chose comme :
for i in $pid $pid2 $pid3 $pid4 $pid5 ; do
wait $(pidof $i)
done
14 sept. 2011 à 16:07
merci de ta réponse.
Je viens de me renseigner un peu sur wait $pid, et d'aprés ce que je pense avoir compris, ce qu'il faudrait faire, c'est en quelque sorte :
-rajouter une variable pour attraper l'ID de chaque lancement de
"recherche_pid_en_direct_sans_duree $i &" en faisant comme cela :
-et ensuite remplacer la boucle while [ $compteurfinal != 0 ] par une boucle du genre
sachant que si le 2eme ID se termine avant le 1er, cela n'a pas d'importance car on ne sort de la boucle que quand les 3 sont terminé?
Est-ce correct de faire de cette façon?
Merci d'avance
14 sept. 2011 à 16:21
15 sept. 2011 à 08:27
Si j'ai bien compris, la fin des processus n'est pas du ressors de ton script. Il se contente d'attendre qu'ils se terminent.
En gros, toute ta première fonction peut être remplacée par le wait $pid (modulo tes tests de contenu de variable), une fois que tu as transformé le $i en $pid. Pour cela, tu peux jeter un oeil du côté de pidof. Il faut juste faire attention à ce que cette commande ne te renvoie pas plusieurs ID.
Du coup tu n'as plus besoin de faire ce polling horrible (while... sleep). Tu as juste à faire quelque chose comme :