Warum nicht bash Herd mit Timeout beendet, wenn es um die Sperre zu erwerben ausfällt?
Frage
Ich spiele mit flock
verwenden, ein Bash-Befehl für Schlösser Datei zwei verschiedene Instanzen des Codes zu verhindern, läuft mehr als einmal.
Ich bin mit diesem Testcode:
( ( flock -x 200 ; sleep 10 ; echo "original finished" ; ) 200>./test.lock ) &
( sleep 2 ; ( flock -x -w 2 200 ; echo "a finished" ) 200>./test.lock ) &
Ich bin mit 2 Subshells (backgrounded). Die (flock NUM; ...) NUM>FILE
Syntax ist von flock
Manpage .
Ich gehe davon aus, dass die erste Sub-Shell wird eine exklusive Sperre für test.lock bekommen, dann warten Sie 10 Sekunden, dann drucken „original fertig“, die ganze Zeit die Sperre hält. Die zweite Unterschale wird in mehr oder weniger gleichzeitig 2 Sekunden warten starten, dann versuchen, eine Sperre auf test.lock zu bekommen, aber Timeout nach 2 Sekunden. Wenn es eine Sperre bekommt, dann wird es drucken „ein fertiges“. Wenn es nicht die Sperre bekommt, sollte diese Subshell stoppen, und nichts sollte gedruckt werden.
Da die erste Subshell länger wartet, wird die Sperre hält für 10 Sekunden, so dass die zweite Subshell nicht die Sperre erhalten soll, und soll nicht beenden. das heißt man sollte sehen "Original fertig" gedruckt und nicht beide.
Was tatsächlich passiert ist, dass „ein fertiger“ gedruckt wird, dann „Original fertig“ gedruckt wird.
Dies bedeutet, dass, dass die zweite Subshell entweder (a) nicht mit der gleichen Sperre wie dem ersten Sub-Shell oder (b), dass es um die Sperre zu bekommen ausfällt, aber weiter auszuführen oder (c) etwas anderes.
Warum nicht diese Schlösser arbeiten, wie ich erwarten?
Lösung
Das Problem, das heißt, wenn der flock
Prozess um die Sperre zu erhalten innerhalb der Timeout fehlschlägt, hat es keine Möglichkeit, den übergeordneten Prozess des Tötens (das heißt die Hülle, die es hervorgebracht) - das alles tun kann, ist ein Fehlerrückgabecode zurück. Sie müssen, dass die Return-Code, bevor Sie fortfahren überprüfen:
flock <params> && <do other stuff>
so
( ( flock -x 200 ; sleep 10 ; echo "original finished" ; ) 200>./test.lock ) & ( sleep 2 ; ( flock -x -w 2 200 && echo "a finished" ) 200>./test.lock ) &
das tut, was Sie wollen.