Sì, c'è davvero una race condition nello script di esempio. Puoi usare noclobber
di bash opzione per ottenere un errore in caso di gara, quando uno script diverso si insinua tra i -f
test e il touch
.
Quello che segue è un frammento di codice di esempio (ispirato a questo articolo) che illustra il meccanismo:
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
Prova il comando flock:
exec 200>"$LOCK_FILE"
flock -e -n 200 || exit 1
Uscirà se il file di blocco è bloccato. È atomico e funzionerà sulla versione recente di NFS.
Ho fatto una prova. Ho creato un file contatore con 0 al suo interno ed eseguito quanto segue in un ciclo su due server contemporaneamente 500 volte:
#!/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 stava combattendo con l'altro per la serratura. Al termine di entrambe le esecuzioni, il contenuto del file era 1000. Ho provato più volte e funziona sempre!
Nota:il client NFS è RHEL 5.2 e il server utilizzato è NetApp.
Blocca il tuo script (contro l'esecuzione parallela)
http://wiki.bash-hackers.org/howto/mutex
PER TUA INFORMAZIONE.