Oui je sais, tout le monde sait faire, mais ce que je propose est un truc tout couillon et quasi automatique.
C’est venu du problème suivant: je récupère de gros fichiers de chez un collègue via rsync. Je le fais une fois par jour (via cron), et il se peut que la synchro prenne plus d’une journée. Et j’ai pas envie que mon script de synchro se lance plusieurs fois. C’est donc un problème d’instance: je ne veux qu’une instance de mon script à un moment donné.
Voilà la fonction adequat, avé les commentaires:
# Fournit un mécanisme de lock: empêche plusieurs instances
# de tourner en même temps.
# Et efface le fichier de lock en sortant
# Utilisation:
# lockme fichier_de_lock
lockme(){
# Fichier de lock: fichier passé en paramètre
lock=$1
# s'il existe, c'est qu'une instance du programme tourne, donc on sort, non sans avoir annoncé le numéro du process qui tournait (des qu'on voudrait le tuer
if [ -e $lock ]
then
echo "An instance is running (`cat $lock`)." & exit
else
# sinon, je crée le fichier en y mettant le pid du process courant
echo "$$" > $lock
# Et là, c'est la ruse: je positionne un trap qui dit que quand le programme sort (le '0' à la fin) il efface le lock. Magique
trap "echo '(cleaning)' ; rm -f $lock" 0
fi
}
Exemple complet? Exemple complet.
touch test.sh
chmod +x test.sh
vi test.sh
#!/bin/bash
lockme(){
lock=$1
if [ -e $lock ]
then
echo "An instance is running (`cat $lock`)." & exit
else
echo "$$" > $lock
trap "echo '(cleaning)' ; rm -f $lock"
fi
}
# notez que le fichier de lock NE DOIT PAS être un truc du genre `mktemp -u`, sinon plusieurs instances tourneront inévitablement!
lock=/tmp/zetestlock
lockme $lock
sleep 1000
Puis faites:
./test.sh &
./test.sh
An instance is running (7937).
Yeah!
PS: Wordpress c’est de la m…. pour l’insertion de code.