Ja, es gibt tatsächlich eine Racebedingung im Beispielskript. Sie können noclobber
von bash verwenden Option, um im Falle eines Rennens einen Fehler zu bekommen, wenn sich ein anderes Skript zwischen die -f
einschleicht test und die touch
.
Das Folgende ist ein Beispiel-Code-Snippet (inspiriert von diesem Artikel), das den Mechanismus veranschaulicht:
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
Versuchen Sie den Flock-Befehl:
exec 200>"$LOCK_FILE"
flock -e -n 200 || exit 1
Es wird beendet, wenn die Sperrdatei gesperrt ist. Es ist atomar und funktioniert über die neueste Version von NFS.
Ich habe einen Test gemacht. Ich habe eine Zählerdatei mit 0 darin erstellt und Folgendes in einer Schleife auf zwei Servern gleichzeitig 500 Mal ausgeführt:
#!/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
Ein Knoten kämpfte mit dem anderen um die Sperre. Als beide Läufe beendet waren, war der Dateiinhalt 1000. Ich habe es mehrmals versucht und es funktioniert immer!
Hinweis:Der NFS-Client ist RHEL 5.2 und der verwendete Server ist NetApp.
Sperren Sie Ihr Skript (gegen Parallellauf)
http://wiki.bash-hackers.org/howto/mutex
FYI.