2010-10-09 9 views
12

Ich schreibe eine Anwendung, die wie ein Filter funktioniert: Es liest die Eingabe aus einer Datei (stdin), verarbeitet und schreibt die Ausgabe in eine andere Datei (stdout). Die Eingabedatei wird vollständig gelesen, bevor die Anwendung mit dem Schreiben der Ausgabedatei beginnt.Verwenden der gleichen Datei für Stdin und Stdout mit Umleitung

Da ich stdin und stdout bin mit, kann ich laufen ist wie folgt:

$ ./myprog <file1.txt >file2.txt 

Es funktioniert gut, aber wenn ich versuche, die gleiche Datei als Eingabe und Ausgabe zu verwenden (das heißt: Lesen von eine Datei und schreiben in die gleiche Datei), wie folgt aus:

$ ./myprog <file.txt >file.txt 

es reinigt file.txt, bevor das Programm die Möglichkeit, es zu lesen hat.

Gibt es eine Möglichkeit, wie ich etwas in einer Befehlszeile in Unix tun kann?

Antwort

13

Die Shell ist was Clobbers Ihre Ausgabedatei, wie es die Ausgabe Dateihandles vor Ausführung Ihres Programms vorbereitet. Es gibt keine Möglichkeit, Ihr Programm dazu zu bringen, die Eingabe zu lesen, bevor die Shell die Datei in einer einzigen Shell-Befehlszeile überkreuzt.

Sie benötigen zwei Befehle verwenden, entweder durch das Verschieben oder Kopieren der Datei, bevor es zu lesen:

mv file.txt filecopy.txt 
./myprog <filecopy.txt> file.txt 

Oder aber auf eine Kopie ausgibt und dann ersetzt das Original:

./myprog <file.txt> filecopy.txt 
mv filecopy.txt file.txt 

Wenn Sie können Tun Sie das nicht, dann müssen Sie den Dateinamen an Ihr Programm übergeben, das die Datei im Lese-/Schreibmodus öffnet und alle E/A intern verarbeitet.

./myprog file.txt     # reads and writes according to its own rules 
8

Für eine Lösung einer rein akademischen Natur:

$ (unlink file.txt && ./myprog >file.txt) <file.txt 

Möglicherweise problematische Nebenwirkungen sind:

  • Wenn ./myprog fehlschlägt, können Sie Ihre Eingabe zerstören. (Natürlich ...)
  • ./myprog läuft von einer Subshell (Use { ... ; } statt (...) zu vermeiden.)
  • file.txt wird eine neue Datei mit einer neuen inode und Dateiberechtigungen.
  • Sie benötigen +w Erlaubnis auf dem Verzeichnis Gehäuse file.txt.
+0

Seltsam. Warum funktioniert "$ (./myprog> file.txt) TheoYou

+0

Ihr Beispiel tut das, weil '> file.txt' den Inhalt von file.txt abschneidet und das ist zufällig die gleiche Datei, von der ' file.txt' eine * neue Datei * (unterschiedliche Inode im selben Pfad)) das ist getrennt von dem, was ' antak

+0

Alles, was wir tun müssen, ist, die Sub-Shell selbst zu starten. Ich denke, ich weiß die Antwort, aber ich bin mir immer noch nicht sicher, warum ... – TheoYou

15

Es gibt ein Schwamm-Dienstprogramm in moreutils Paket:

./myprog < file.txt | sponge file.txt 

das Handbuch zu zitieren:

Sponge Standardeingabe liest und schreibt sie in die angegebene Datei aus. Im Gegensatz zu einer Shell-Weiterleitung nimmt Schwamm alle Eingaben auf, bevor die Ausgabedatei geöffnet wird. Dies ermöglicht das Konstruieren von Pipelines, die von derselben Datei lesen und in dieselbe Datei schreiben.

+1

Bitte, erarbeiten Sie Ihre Antwort. – Beppe

Verwandte Themen