2017-10-15 12 views
0

J'ai une fonction dans un script bash qui s'exécute indéfiniment en arrière-plan et qui doit être terminée en exécutant à nouveau le même script. C'est une sorte de commutateur, quand j'appelle ce script il commence ou tue la fonction s'il est déjà en cours d'exécution. Pour ce faire, j'utiliser un fichier PID:verrouillage d'un fichier PID

#!/bin/bash 

background_function() { 
    ... 
} 

if [[ ! -s myscript.pid ]] 
then 
    background_function & 
    echo $! > myscript.pid 
else 
    kill $(cat myscript.pid) && rm myscript.pid 
fi 

Maintenant, je voudrais éviter plusieurs instances en cours d'exécution et les conditions de course. J'ai essayé d'utiliser troupeau et je réécrit le code ci-dessus ainsi:

#!/bin/bash 

background_function() { 
    ... 
} 

exec 200>myscript.pid 
if flock -n 200 
then 
    background_function & 
    echo $! > myscript.pid 
else 
    kill $(cat myscript.pid) && rm myscript.pid 
fi 

Ce faisant, cependant, j'ai un verrou sur le fichier pid mais chaque fois que je lance à nouveau le script le fichier pid est réécrite par exec 200>myscript.pid et par conséquent, je suis incapable de récupérer le PID de l'instance en cours d'exécution et le tuer.

Que puis-je faire? Dois-je utiliser deux fichiers différents, un fichier pid et un fichier de verrouillage? Ou serait-il préférable d'implémenter d'autres mécanismes de verrouillage en utilisant mkdir et touch? Merci.

Répondre

0

Si un echo $$ est assez atomique pour vous, vous pouvez utiliser:

echo $$ >> lock.pid 
lockedby=`head -1 lock.pid` 
if [ $$ != $lockedby ] ; then 
    kill -9 $lockedby 
    echo $$ > lock.pid 
    echo "Murdered $lockedby because it had the lock" 
fi 

# do things in the script 

rm lock.pid 
+0

Il est une approche intéressante et il fonctionne pour moi. La seule partie délicate consiste à réécrire le fichier PID avec le PID correct du processus en arrière-plan ('background_function &; echo $!> Lock.pid'). Je vous remercie! –