Scripte mit Lockfile
Immer wieder gibt es Prozesse die sehr lange dauern und die auf keinen Fall doppelt gestartet werden sollten. Vor vielen Jahren bin ich über eine Lösung für Lockfiles in Bash-Scripten gestolpert, die ich seitdem in fast jedem Script mit potenziell langer Laufzeit nutze.
LOCKFILE="/var/lock/$(basename $0)"
LOCKFD=99
_lock() { flock -$1 $LOCKFD; }
_no_more_locking() { _lock u; _lock xn && rm -f $LOCKFILE; }
_prepare_locking() { eval "exec $LOCKFD>\"$LOCKFILE\""; trap _no_more_locking EXIT; }
_prepare_locking
exlock_now() { _lock xn; } # obtain an exclusive lock immediately or fail
exlock() { _lock x; } # obtain an exclusive lock
shlock() { _lock s; } # obtain a shared lock
unlock() { _lock u; } # drop a lock
exerror() { echo "$1";exit "${2:-1}"; }
exlock_now || exerror "ERROR: Lockfile exists, is there another instance already running? Exiting..."
Das Script erzeugt eine Datei in /var/lock/
die den Namen des aufgerufenen Scripts trägt. Sie erhält den File-Descriptor1 99
. Gesetzt und wieder entfernt wird das Lockfile mit dem Befehl flock
2. Es ist dabei aber nicht zwingend nötig am Ende des Script die unlock
Funktion aufzurufen. Endet das Script wird das Lockfile automatisch entfernt.
Solange die Lockfiledatei existiert, bricht das Script direkt nach dem Start mit der Fehlermeldung ERROR: Lockfile exists, is there another instance already running? Exiting...
ab.
Ich nutze diese Funktion z.B. in Backupscripten, die gerne einmal viele Stunden laufen. Da ich meistens Backuptools nutze, die spezielle Repoformate nutzen, sollten diese niemals doppelt gestartet werden. Die Tools selbst haben zwar eigene Lockfiles um genau das zu verhindern, aber ich erzeuge für Backups meistens Snapshots oder starte spezielle Tools zum Sichern von Datenbanken. Auch diese Prozesse sollten nicht doppelt gestartet werden. Vor allem sollte aber das Script beim Beenden nicht die gemounteten Snapshot entfernen und diese ggf. auch für die zuvor gestartete Backupinstanz entfernen.