Sí, de hecho hay una condición de carrera en el script de muestra. Puedes usar noclobber
de bash opción para obtener una falla en caso de una carrera, cuando un script diferente se cuela entre el -f
prueba y el touch
.
El siguiente es un fragmento de código de muestra (inspirado en este artículo) que ilustra el mecanismo:
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
Prueba el comando de rebaño:
exec 200>"$LOCK_FILE"
flock -e -n 200 || exit 1
Saldrá si el archivo de bloqueo está bloqueado. Es atómico y funcionará con la versión más reciente de NFS.
Hice una prueba. Creé un archivo de contador con 0 y ejecuté lo siguiente en un bucle en dos servidores simultáneamente 500 veces:
#!/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 nodo estaba luchando con el otro por la cerradura. Cuando ambas ejecuciones terminaron, el contenido del archivo era 1000. ¡Lo intenté varias veces y siempre funciona!
Nota:el cliente NFS es RHEL 5.2 y el servidor utilizado es NetApp.
Bloquee su secuencia de comandos (contra la ejecución en paralelo)
http://wiki.bash-hackers.org/howto/mutex
para tu información