Flock scheint nicht zu funktionieren


7

Ich habe kürzlich versucht, ein Shell-Skript für ein kleines Projekt zu erstellen, und aus irgendeinem Grund flockfunktioniert der Befehl bei mir nicht richtig. Immer wenn ich es auf atomare Weise in einer Subshell aufrufe und in den Hintergrund stelle, scheinen andere Programme in der Lage zu sein, aus der gesperrten Datei zu lesen / in diese zu schreiben.

Bash-Sitzung:

guest@guest ~ $ touch ./temp
guest@guest ~ $ ( flock -x 3 && sleep 99999999999; ) 3>./temp &
[1] 22874
guest@guest ~ $ cat ./temp 
guest@guest ~ $ echo this is a test >./temp 
guest@guest ~ $ cat ./temp 
this is a test
guest@guest ~ $ jobs
[1]+  Running                 ( flock -x 3 && sleep 99999999999 ) 3>./temp &
guest@guest ~ $ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Ich habe das Gefühl, dass mir etwas sehr Einfaches in Bezug auf die Interna des 'Flock'-Programms fehlt, aber ich weiß nicht, was es sein könnte.

Antworten:


8

flockberät, was ein kooperatives Sperrschema ist. Dies bedeutet, dass Sie die Sperre überschreiben können, wenn Sie nicht kooperieren. Sie arbeiten zusammen, indem Sie die Sperre anfordern, bevor Sie den Vorgang ausführen, und dann die Sperre aufheben, nachdem Sie fertig sind. Es ist die Operation, die durch die Sperre geschützt ist, nicht (notwendigerweise) die Sperrdatei selbst.

Aus dem flock(2)Handbuch auf meinem System:

Beratungssperren ermöglichen es kooperierenden Prozessen, konsistente Vorgänge für Dateien auszuführen, garantieren jedoch keine Konsistenz (dh Prozesse können weiterhin auf Dateien zugreifen, ohne Beratungssperren zu verwenden, was möglicherweise zu Inkonsistenzen führt).

Betrachten Sie dieses Skript:

#!/bin/sh

( flock -x 9 || exit 1
  echo '1: Locking for 5 secs'; sleep 5; echo '1: Done' ) 9>/tmp/lock &

sleep 1
echo '2: Will now attempt to get lock'

( flock -x 9 || exit 1
  echo '2: Got lock' ) 9>/tmp/lock

# Since the second flock call only performs one operation, the whole last 
# subshell may be replaced by just
#    flock -x /tmp/lock -c echo '2: Got lock'
#
#  (-x and -c are not needed, a lock is exclusive ("write lock")
#   unless -s is used to create a shared lock ("read lock"),
#   and the -c is optional)

Ausgabe:

1: Locking for 5 secs
2: Will now attempt to get lock
1: Done
2: Got lock

Sie können sehen, dass die Sperre vom Hintergrundprozess erfasst wurde und dass der andere flockAufruf warten musste, bis sie freigegeben wurde, bevor er gesperrt werden konnte.

Beachten Sie auch, dass die Sperrdatei hier nicht geschützt ist, sondern dass die echoVorgänge in den Subshells garantiert exklusiv sind. Insbesondere ist die Sperrdatei nicht vor nicht kooperativen Prozessen geschützt, die daraus schreiben oder lesen.

Dies bedeutet , dass jeder flockSubshell, durch Sperren /tmp/lockin diesem Beispiel wird garantiert , dass die Operationen (auf Dateien oder anderen freigegebenen Datenressourcen) nicht mit widerstreitenden Operationen von verwirbelt werden jedes anderes Programm , dass Anwendungen flockmit /tmp/lockals Sperrdatei.

Um den letzten Absatz oben zu veranschaulichen, führen Sie mein Skript oben in zwei verschiedenen Terminals (möglicherweise mit leicht erhöhter Ruhezeit) so gleichzeitig wie möglich aus und stellen Sie sicher, dass die beiden konkurrierenden Skripte die Sperren ordnungsgemäß erwerben (aufeinander warten). Da in einem Hintergrundprozess eine Sperre angefordert wird, bedeutet dies, dass die Sperren möglicherweise nicht in der richtigen Reihenfolge von den im Skript angegebenen Sätzen abgerufen werden, wenn zwei Instanzen des Skripts gleichzeitig ausgeführt werden.

In Ihrem Beispiel arbeitet die interaktive Shell nicht mit dem Sperrmechanismus zusammen . Aus diesem Grund können Sie aus der Datei lesen und in sie schreiben, obwohl die Sperre von der Hintergrund-Subshell gehalten wird.

Beachten Sie auch, dass möglicherweise nicht alle Dateisysteme das Sperren von Dateien mit flock(oder der entsprechenden C-Bibliothek flock()) unterstützen. Beispielsweise können die Netzwerkdateisysteme AFS und NFS in dieser Hinsicht problematisch sein. Siehe https://en.wikipedia.org/wiki/File_locking#Problems


Ugh, die unglücklichen Wahrheiten ...
Mr. Minty Fresh
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.