Oui, il y a bien une condition de concurrence dans l'exemple de script. Vous pouvez utiliser le noclobber
de bash option afin d'obtenir un échec en cas de course, lorsqu'un script différent se faufile entre les -f
test et le touch
.
Voici un exemple d'extrait de code (inspiré de cet article) qui illustre le mécanisme :
if (set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null;
then
# This will cause the lock-file to be deleted in case of a
# premature exit.
trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
# Critical Section: Here you'd place the code/commands you want
# to be protected (i.e., not run in multiple processes at once).
rm -f "$lockfile"
trap - INT TERM EXIT
else
echo "Failed to acquire lock-file: $lockfile."
echo "Held by process $(cat $lockfile)."
fi
Essayez la commande flock :
exec 200>"$LOCK_FILE"
flock -e -n 200 || exit 1
Il se fermera si le fichier de verrouillage est verrouillé. Il est atomique et fonctionnera sur la version récente de NFS.
J'ai fait un essai. J'ai créé un fichier de compteur contenant 0 et exécuté ce qui suit en boucle sur deux serveurs simultanément 500 fois :
#!/bin/bash
exec 200>/nfs/mount/testlock
flock -e 200
NO=`cat /nfs/mount/counter`
echo "$NO"
let NO=NO+1
echo "$NO" > /nfs/mount/counter
Un nœud se battait avec l'autre pour le verrou. Lorsque les deux exécutions sont terminées, le contenu du fichier était de 1 000. J'ai essayé plusieurs fois et cela fonctionne toujours !
Remarque :le client NFS est RHEL 5.2 et le serveur utilisé est NetApp.
Verrouillez votre script (contre l'exécution en parallèle)
http://wiki.bash-hackers.org/howto/mutex
POUR VOTRE INFORMATION.