Ano, ve vzorovém skriptu skutečně existuje sporná podmínka. Můžete použít bash noclobber
možnost, aby došlo k selhání v případě závodu, kdy se mezi -f
vplíží jiný skript test a touch
.
Následuje ukázkový fragment kódu (inspirovaný tímto článkem), který ilustruje mechanismus:
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
Zkuste příkaz flock:
exec 200>"$LOCK_FILE"
flock -e -n 200 || exit 1
Ukončí se, pokud je soubor zámku uzamčen. Je atomický a bude fungovat na nejnovější verzi NFS.
Udělal jsem test. Vytvořil jsem soubor čítače s 0 a provedl jsem následující ve smyčce na dvou serverech současně 500krát:
#!/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
Jeden uzel bojoval s druhým o zámek. Po dokončení obou běhů byl obsah souboru 1000. Zkoušel jsem to několikrát a vždy to funguje!
Poznámka:Klient NFS je RHEL 5.2 a použitý server je NetApp.
Uzamkněte skript (proti paralelnímu běhu)
http://wiki.bash-hackers.org/howto/mutex
FYI