Warum liest und schreibt die gleiche Datei über die I / O-Umleitung eine leere Datei in Unix?

7

Wenn ich die Ausgabe eines Befehls in dieselbe Datei umleite, von der sie liest, wird ihr Inhalt gelöscht.

%Vor%

Kann jemand erklären, warum?

    
Venkataramesh Kommoju 13.12.2009, 09:17
quelle

4 Antworten

16

Das erste, was die Umleitung macht, ist, die Datei zum Schreiben zu öffnen, wodurch alle vorhandenen Inhalte gelöscht werden. sed versucht dann, diese leere Datei zu lesen, die Sie gerade erstellt haben, und tut nichts. Die Datei wird geschlossen und enthält nichts.

    
anon 13.12.2009, 09:23
quelle
8

Die Umleitungsoperationen < , > usw. werden von der Shell gehandhabt. Wenn Sie der Shell, die die Umleitung enthält, einen Befehl geben, öffnet die Shell zuerst die Datei. Im Fall von > wird die Datei zum Schreiben geöffnet, was bedeutet, dass sie auf die Größe Null gekürzt wird. Nachdem die Umleitungsdateien geöffnet wurden, startet die Shell einen neuen Prozess, bindet die Standardeingabe, -ausgabe und den Fehler an alle möglicherweise umgeleiteten Dateien und führt erst dann den von Ihnen angegebenen Befehl aus. Wenn der Befehl sed in Ihrem Beispiel die Ausführung beginnt, wurde a.txt bereits von der Shell abgeschnitten.

Übrigens, und etwas tangential, ist dies auch der Grund, warum Sie die Umleitung nicht direkt mit sudo verwenden können, da die Shell die Berechtigungen benötigt, um die Umleitungsdatei zu öffnen, nicht den ausgeführten Befehl.

    
JaakkoK 13.12.2009 09:40
quelle
1

Sie müssen die Option -i verwenden, um die Datei vor Ort zu bearbeiten:

  

sed -i .bck 's / abd / def / g' a.txt

EDIT: wie von Neil bemerkt, öffnet die Umleitung zuerst die Datei zum Schreiben und löscht sie damit.

EDIT2: es könnte für einige Leser interessant sein

Wenn Sie auf OSX -i mit einer leeren Erweiterung verwenden möchten, um die Erstellung einer Sicherungsdatei zu verhindern, müssen Sie auch den Schalter -e verwenden, da andernfalls die Argumente nicht korrekt analysiert werden können:

  

sed -i -e 's / abc / def / g' a.txt

    
Gregory Pakosz 13.12.2009 09:23
quelle
0

stdout und stderr werden zuerst vorbereitet und dann stdin und dann wird der Befehl ausgeführt. so a.txt wäre zuerst für stdout und dann, wenn das comundnd ausgeführt wird, konnte kein Inhalt gefunden werden. Versuchen sed -is '/ abd / def / g' a.txt oder sed 's / abd / def / g' a.txt 1 & lt; & gt; a.txt

    
Travis 17.11.2016 11:22
quelle

Tags und Links