[Eisfair] Fragen
Christoph Schulz
fli4l at kristov.de
Fr Jun 10 23:29:46 CEST 2016
Hallo!
Marcus Roeckrath schrieb:
> Ich verwende in Skripten, die besser nicht mehrfach (parallel) gestartet
> werden dürfen, folgenden Code:
>
> if [ -f /tmp/my_skript.running ] ; then
> exit 1
> fi
>
> touch /tmp/my_skript.running
Das ist aber auch eine "race condition", da Testen-und-Setzen nicht atomar
ist. Es könnte sein, dass zwei Skript-Prozesse gleichzeitig starten, beide
feststellen, dass die Datei /tmp/my_skript.running nicht existiert, beide
diese Datei via "touch" erzeugen (einer erzeugt, der andere aktualisiert nur
den Zeitstempel der letzten Änderung) und dann beide parallel ausgeführt
werden.
Eine funktionierende Möglichkeit unter Linux ist, eine symbolische
Verknüpfung zu erzeugen, weil das immer atomar ist:
if ! ln -s /tmp/my_skript.$$ /tmp/my_skript.running 2>/dev/null; then
exit 1
fi
[...]
rm -f /tmp/my_skript.running
Man beachte, dass das Ziel der Verknüpfung (also /tmp/my_skript.$$) gar
nicht existieren muss.
Will man auf Nummer sicher gehen, dass das Aufräumen nicht vergessen wird,
steckt man das Löschen in einen Shell-Exit-Hook:
trap "[ \"\`readlink /tmp/my_skript.running\`\" = /tmp/my_skript.$$ ] &&
rm -f /tmp/my_skript.running" EXIT
if ! ln -s /tmp/my_skript.$$ /tmp/my_skript.running 2>/dev/null; then
exit 1
fi
[...]
Dann wird immer aufgeräumt, auch wenn das Skript abbricht oder durch ein
Signal wie SIGHUP beendet wird. Der etwas kompliziert anmutende Vergleich
mit readlink stellt sicher, dass die /tmp/my_skript.running-Verknüpfung nur
dann gelöscht wird, wenn das Skript sie auch besitzt, was an der Prozess-ID
($$) festgemacht wird, die im Ziel der symbolischen Verknüpfung kodiert ist.
(Ein Zurücksetzen des Shell-Exit-Hooks direkt vor dem "exit 1" via "trap -
EXIT" ist nicht sicher, weil das Skript zwischen einem fehlgeschlagenem ln-
Aufruf und dem trap-Befehl von außen durch ein Signal beendet werden
könnte.)
Viele Grüße,
--
Christoph Schulz
[fli4l-Team]
Mehr Informationen über die Mailingliste Eisfair