Wendet die Umleitung der Ausgabe in eine Datei eine Dateisperre an?

30

Wenn ich einen Befehl habe

$ ./script >> file.log

Das wird zweimal aufgerufen. Der zweite Anruf wird ausgeführt, bevor der erste beendet wird. Was passiert dann?

Erhält der erste Aufruf eine exklusive Sperre für die Ausgabedatei? Wenn ja, schlägt das zweite Skript fehl, wenn versucht wird zu schreiben, oder akzeptiert die Shell die Ausgabe (damit das Skript beendet werden kann) und gibt einen Fehler aus?

Oder wird die Protokolldatei zweimal geschrieben?


quelle
1
Ich kenne kein System, das die Datei standardmäßig sperren würde. Was wahrscheinlicher ist, ist, dass die beiden Programme ihre Schreibvorgänge verschachteln, da sich beide im Anhänge-Modus befinden. Die Ergebnisse wären eher unvorhersehbar. Anstelle von "Hallo Welt" könnte man "hweolrllod" bekommen.
Jw013

Antworten:

18

Da Sie " >>Anhängen" verwenden, wird jede Ausgabezeile von jeder Instanz in der Reihenfolge angehängt, in der sie aufgetreten ist.

Wenn Ihre Skript - Ausgabe druckt 1\ndurch 5\nmit einer Verzögerung von einer Sekunde zwischen jedem Fall zwei gestartet 2,5 Sekunden später werden Sie diese:

1
2
1
3
2
4
3
5
4
5

Um Ihre Frage zu beantworten: Nein.

Bahamat
quelle
23

Unix-Systeme vermeiden im Großen und Ganzen obligatorische Sperren. Es gibt einige Fälle, in denen der Kernel eine Datei gegen Änderungen durch Benutzerprogramme sperrt, jedoch nicht, wenn sie lediglich von einem anderen Programm geschrieben wird. Kein Unix-System sperrt eine Datei, weil ein Programm darauf schreibt.

Wenn Sie möchten, dass gleichzeitige Instanzen Ihres Skripts sich nicht gegenseitig stören, müssen Sie einen expliziten Sperrmechanismus verwenden, z .flock lockfile

Wenn Sie eine Datei zum Anhängen öffnen, >>schreibt jedes Programm garantiert immer an das Ende der Datei. Die Ausgabe mehrerer Instanzen überschreibt sich also nie gegenseitig, und wenn sie abwechselnd schreiben, erfolgt die Ausgabe in derselben Reihenfolge wie die Schreibvorgänge.

Das Schlimme, was passieren könnte, ist, wenn eine der Instanzen mehrere Ausgabestücke schreibt und erwartet, dass sie zusammenkommen. Zwischen aufeinanderfolgenden Schreibvorgängen einer Instanz können andere Instanzen ihre eigenen Schreibvorgänge ausführen. Wenn beispielsweise Instanz 1 schreibt foo, Instanz 2 schreibt hellound nur Instanz 2 schreibt bar, enthält die Datei Folgendes foohellobar.

Ein Prozess schreibt effektiv in die Datei, wenn er den writeSystemaufruf aufruft . Ein Aufruf von writeist atomar: Jeder Aufruf von writeschreibt eine Folge von Bytes, die nicht von anderen Programmen unterbrochen werden. Die Anzahl der Daten, die mit einem einzelnen Aufruf writeeffektiv geschrieben werden sollen, ist häufig begrenzt : Bei größeren Größen wird nur der Anfang der Daten geschrieben, und die Anwendung muss writeerneut aufrufen . Darüber hinaus führen viele Programme eine Pufferung durch: Sie akkumulieren Daten in einem Speicherbereich und schreiben diese Daten dann in einem Block aus. Einige Programme leeren den Ausgabepuffer nach einer vollständigen Zeile oder einer anderen sinnvollen Trennung. Mit solchen Programmen können Sie erwarten, dass ganze Zeilen nicht unterbrochen werden, solange sie nicht zu lang sind (bis zu einigen Kilobyte; dies hängt vom Betriebssystem ab). Wenn das Programm nicht an wichtigen Stellen, sondern nur anhand der Puffergröße leert, sehen Sie möglicherweise 4 KB von einer Instanz, dann 4 KB von einer anderen Instanz, dann wieder 4 KB von der ersten Instanz und so weiter.

Gilles 'SO - hör auf böse zu sein'
quelle