Ich habe Probleme zu verstehen, was passiert, wenn ich versuche, in einen Dateideskriptor zu schreiben. Es scheint den ursprünglichen Inhalt zu überschreiben? Ist das erwartetes Verhalten?
Ich habe dies im folgenden Beispiel wiederholt:
$ echo "The quick brown fox ..." > example.txt
$ echo "The quick brown fox ..." >> example.txt
$ cat example.txt
The quick brown fox ...
The quick brown fox ...
$ exec 88<>example.txt
$ cat example.txt
The quick brown fox ...
The quick brown fox ...
$ echo "jumped" >&88
$ cat example.txt
jumped
ck brown fox ...
The quick brown fox ...
$ echo "jumped" >&88
$ cat example.txt
jumped
jumped
n fox ...
The quick brown fox ...
cat example.txt
, öffnet cat die Datei, erhält einen Deskriptor mit einer Suchposition , die am Anfang der Datei beginnt, liest sie bis zum Ende und schließt dann den Deskriptor. Wenn Sie ausführenexec 88<>example.txt
, öffnet bash die Datei und erhält einen Deskriptor mit einer Suchposition, die am Anfang der Datei beginnt. Die Datei selbst behält keine Suchposition bei, stattdessen wird für jeden geöffneten Dateideskriptor eine Position beibehalten.cat <&88
zuerst schreiben, handelt es sich bei den folgenden Schreibvorgängen nur um reguläre Schreibvorgänge an der Stelle, an der das Schreiben gestoppt wurde, und nicht um ordnungsgemäße Anhänge. Sie könnten in der Zwischenzeit Daten überschreiben, die von einem anderen Prozess geschrieben wurden. Wenn das Anhängen gewünscht wird, ist der>>
Umleitungsoperator der (einzige) Weg. Soweit ich weiß, hat Bash nicht wirklich die Möglichkeit, Dateien zu suchen, und es erlaubt auch nicht, gleichzeitig im Lese- / Schreibmodus und im Anhänge-Modus zu öffnen .Wie @Zoonose richtig hervorhebt, hat jeder Dateideskriptor seine eigene Lese- / Schreib-Cursorposition in der Datei, mit der er verbunden ist. Und eine Datei kann entweder von der Shell geöffnet werden, wenn Sie eine Umleitung wie verwenden
<>
, oder von einem Programm wiecat
.Die Zahlen, die Sie als "Filedescriptor" betrachten, sind jedoch nur Verweise auf die tatsächlichen Filedescriptors im Kernel, und es ist völlig normal, dass ein Filedescriptor mehrere solcher Referenznummern hat, entweder innerhalb eines einzelnen Prozesses oder zwischen Prozessen.
Wenn Sie also ein Terminalfenster öffnen (oder sich mit ssh anmelden), beginnen Sie mit einem einzelnen Dateiskriptor, der für Ihr Terminal geöffnet ist und in Ihrem Shell-Prozess als fd # 0, fd # 1 und fd # 2 verbunden ist. Jeder Prozess, mit dem die Shell beginnt, erbt diese standardmäßig - außer wenn Sie Pipes oder Umleitungen verwendet haben.
Die Umleitung
>>
kennzeichnet den Dateiskriptor alsO_APPEND
, sodass beim Schreiben durch diesen Dateiskriptor der Cursor ignoriert wird und zum Ende der Datei gewechselt wird.Durch die Umleitung
>
wird die Zieldatei nur einmal abgeschnitten, bevor geschrieben wird. Daher wird jedes Schreiben danach normalerweise in den leeren Bereich nach dem Ende der Datei verschoben.Writes in einer Datei tun nicht selbst Ursache Abschneiden; Sie ersetzen einfach alles, was sich an der aktuellen Position befindet, und strecken bei Bedarf das Dateiende.
Beachten Sie,
somecmd >&88
dass das stdout (fd # 1) für somecmd den Dateiskriptor mit fd # 88 der aktuellen Shell teilt. Das heißt, es wird dieO_APPEND
Option teilen , falls vorhanden. Es wird nicht dazu führen, dass es erneut abgeschnitten wird. Das ist eine einmalige Sache.Was Sie in diesem Fall sehen, ist, dass es bei der Verwendung keine Kürzung gibt
>&88
, da fd # 88 nicht mit geöffnet>>
wurde und daher Schreibvorgänge aus mehreren Prozessen verschachtelt werden können.quelle