Eine einfache und scheinbar zuverlässige Methode, um unter bash zu sperren, ist:
%Vor%Allerdings propagiert bash notorisch eine solche fd-Sperre auf alle gegabelten Dinge einschließlich der ausgeführten Programme usw.
Gibt es eine Möglichkeit, bash zu sagen, die fd nicht zu duplizieren? Es ist großartig, dass die Sperre an ein fd angehängt ist, das entfernt wird, wenn das Programm beendet wird, egal wie es beendet wird.
Ich weiß, ich kann Sachen machen wie:
%Vor%Aber das ist ziemlich langweilig.
Gibt es eine bessere Lösung?
Sie können die Befehlszeilenoption -o
für flock(1)
(lange Option --close
, die zum Schreiben in Skripten für die selbstdokumentierende Natur besser geeignet ist) verwenden, um anzugeben, dass der Dateideskriptor vor der Ausführung geschlossen werden sollte Befehle über flock(1)
:
Anscheinend flock -o FD
behebt das Problem nicht. Ein Trick, um die überflüssige FD für spätere Befehle in demselben Shell-Skript loszuwerden, besteht darin, den verbleibenden Teil in einen Abschnitt zu wickeln, der die FD wie folgt schließt:
Das ist ein bisschen CLUMSY
, weil das Schließen der FD so weit von der Sperre entfernt ist.
Sie können diesen "natürlichen" Befehlsfluss umgestalten, aber Dinge zusammenhalten, die zusammengehören:
%Vor%Ein etwas netteres Schreiben, das den natürlichen Befehlsfluss auf Kosten einer anderen Gabel hält, plus einen zusätzlichen Prozess und einen etwas anderen Arbeitsablauf, der oft nützlich ist. Dies erlaubt jedoch nicht das Setzen von Variablen in der äußeren Shell :
%Vor% Übrigens, wenn Sie wirklich sicher sein wollen, dass bash
keine zusätzlichen Dateideskriptoren einführt (um die geschlossene FD zu "verstecken" und eine echte Gabelung zu überspringen), zum Beispiel wenn Sie etwas Deamon ausführen, das dann die Sperre halten würde Für immer wird die letztere Variante empfohlen, nur um sicher zu sein. lsof -nP
und strace your_script
sind deine Freunde.
Es gibt keine Möglichkeit, eine FD als close-on-exec innerhalb der bash zu markieren, also gibt es keine bessere Lösung.
-o
funktioniert nicht mit Dateideskriptoren, es funktioniert nur mit Dateien. Sie müssen -u
verwenden, um den Dateideskriptor zu entsperren.
Was ich mache ist das:
%Vor%Auf diese Weise wird der Dateideskriptor durch den Prozess, der die Sperre vorgenommen hat, geschlossen, und da jeder andere Prozess beendet wird, wird nur der Prozess, der die Sperre hält, den Dateideskriptor entsperren und die Sperrdatei entfernen.
Tags und Links bash locking file-descriptor