Wird durch die Umleitung der Ausgabe in eine Datei eine Sperre für die Datei angewendet?

Wird durch die Umleitung der Ausgabe in eine Datei eine Sperre für die Datei angewendet?

Wenn ich einen Befehl habe

$ ./script >> file.log

das zweimal aufgerufen wird, wobei der zweite Aufruf erfolgt, bevor der erste beendet ist. Was passiert?

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

Oder wird die Logdatei doppelt beschrieben?

Antwort1

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 in sie schreibt.

Wenn Sie möchten, dass sich gleichzeitig ausgeführte Instanzen Ihres Skripts nicht gegenseitig in die Quere kommen, müssen Sie einen expliziten Sperrmechanismus verwenden, wie z. B.flock lockfile.

Wenn Sie eine Datei zum Anhängen öffnen (was der >>Fall ist), schreibt jedes Programm garantiert immer bis zum Ende der Datei. Die Ausgabe der mehreren Instanzen überschreibt sich also nie gegenseitig, und wenn sie abwechselnd schreiben, erfolgt ihre Ausgabe in derselben Reihenfolge wie die Schreibvorgänge.

Das Schlimmste, was passieren könnte, ist, wenn eine der Instanzen mehrere Ausgabeblöcke schreibt und erwartet, dass diese zusammen ausgegeben werden. Zwischen aufeinanderfolgenden Schreibvorgängen einer Instanz können andere Instanzen ihre eigenen Schreibvorgänge durchführen. Wenn beispielsweise Instanz 1 schreibt foo, dann schreibt Instanz 2 hellound erst dann schreibt Instanz 2 bar, dann enthält die Datei foohellobar.

Ein Prozess schreibt effektiv in die Datei, wenn er den writeSystemaufruf aufruft. Ein Aufruf von writeist atomar: Jeder Aufruf von writeschreibt eine Bytefolge, die nicht von anderen Programmen unterbrochen wird. Es gibt oft eine Grenze dafür, wie viele Daten ein einzelner Aufruf von writeeffektiv schreiben kann: Bei größeren Datenmengen wird nur der Anfang der Daten geschrieben und die Anwendung muss writeerneut aufrufen. Darüber hinaus führen viele ProgrammePufferung: Sie sammeln 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. Bei solchen Programmen können Sie davon ausgehen, dass ganze Zeilen ohne Unterbrechung ausgegeben werden, solange sie nicht zu lang sind (bis zu einigen Kilobyte; dies hängt vom Betriebssystem ab). Wenn das Programm nicht an sinnvollen Stellen leert, sondern nur auf der Grundlage der Puffergröße, sehen Sie möglicherweise etwa 4 KB von einer Instanz, dann 4 KB von einer anderen Instanz, dann wieder 4 KB von der ersten Instanz und so weiter.

Antwort2

Da Sie verwenden >>, was „Anhängen“ bedeutet, wird jede Ausgabezeile jeder Instanz in der Reihenfolge angehängt, in der sie aufgetreten ist.

Wenn die Ausgabe Ihres Skripts mit einer Verzögerung von einer Sekunde zwischen den einzelnen Instanzen ausgedruckt wird 1\nund 5\ndie zweite Instanz 2,5 Sekunden später gestartet wird, erhalten Sie Folgendes:

1
2
1
3
2
4
3
5
4
5

Um also Ihre Frage zu beantworten: Nein.

verwandte Informationen