Pregunta

este es el enfoque estándar para crear bloqueos utilizando el sistema de archivos. Por ejemplo, visudo lo usa:

[ -f ".lock" ] && exit 1
touch .lock
# do something
rm .lock

1) Estoy confundido, porque hay una condición de carrera, pero Linux lo usa

2) ¿hay una mejor manera de bloquear archivos desde el shell?

3) ¿o tengo que usar directorios en su lugar?

Solución encontrada: man lockfile.

¿Fue útil?

Solución

Sí, de hecho hay una condición de carrera en el script de muestra. Puede usar la opción noclobber de bash para obtener una falla en caso de una carrera, cuando un guión diferente se cuela entre la prueba y el toque.

Se describe aquí . He extraído la pieza crítica, con un par de anotaciones (con el prefijo BK :):

  

Una posible solución a esto es usar la redirección de E / S y el modo noclobber de bash, que no redirigirá a un archivo existente. Podemos usar algo similar a:

if ( set -o noclobber; echo "$" > "$lockfile") 2> /dev/null; 
then
   # BK: this will cause the lock file to be deleted in case of other exit
   trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT

   # critical-section BK: (the protected bit)

   rm -f "$lockfile"
   trap - INT TERM EXIT
else
   echo "Failed to acquire lockfile: $lockfile." 
   echo "Held by $(cat $lockfile)"
fi

Otros consejos

Pruebe el comando flock:

exec 200>"$LOCK_FILE"
flock -e -n 200 || exit 1

Saldrá si el archivo de bloqueo está bloqueado. Es atómico y funcionará en una versión reciente de NFS.

Hice una prueba. Creé un archivo 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 el bloqueo. Cuando ambas ejecuciones terminaron, el contenido del archivo era 1000. ¡Lo he intentado varias veces y siempre funciona!

Nota: el cliente NFS es RHEL 5.2 y el servidor utilizado es NetApp.

Bloquee su script (contra ejecución paralela)

http://wiki.bash-hackers.org/howto/mutex

FYI.

parece que he encontrado una solución más fácil: man lockfile

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top