Zuerst leite ich meine Standardausgabe in eine bestimmte Datei um. Kein Problem dort (ich benutzte dup2(fd, 1) wo fd ist der Dateideskriptor für die Datei).
Danach muss ich meine stdout wieder auf das Terminal umleiten.
Da steht illegale Suche.
Keine Ahnung, warum das passiert.
Aber wenn ich das zum Laufen bekomme, dann brauche ich nur zu verwenden fsetpos(stdout, &stream_stdout) und es sollte funktionieren.
Meine zweite Idee war, die Standardausgabe mit zu kopieren dup2(stdout, 4) in die Dateideskriptortabelle, an Position 4. Aber das funktioniert auch nicht.
Wie kann ich die Standardausgabe wieder an ihr ursprüngliches Ziel (Terminal, Pipe, Datei, was auch immer) schalten?
Ich habe das Gefühl, dass ich versuche, mich zu bewegen stdout herum so herum ist wahrscheinlich eine schlechte Idee — welche Position sollte das genau haben Terminal melde dich ein fgetpos()? Warum nicht einfach eine Datei öffnen und mit ausgeben fwrite() oder fprintf() oder write() und über das Terminal ausgegeben /dev/tty wenn du es brauchst?
– Sarnold
14. Juni 2012 um 22:30 Uhr
@sarnold: wahrscheinlich, weil das Programm Bibliotheken oder anderen unveränderlichen Code hat, mit dem fest verdrahtet ist stdout.
– Wallyk
14. Juni 2012 um 22:31 Uhr
@sarnold Ich habe eigentlich nicht an diese Möglichkeit gedacht. Lass mich schnell nachsehen.
– Alessandro Empire
14. Juni 2012 um 22:37 Uhr
Ich habe nicht genug Informationen, um eine gute Antwort zu posten, also kommentiere ich stattdessen. Unter Windows können Sie die Konsole erneut anhängen. Ich würde mir jede Win32-SDK-Dokumentation ansehen. Es ist nicht schwer; Ich kann mich nur nicht erinnern, wie es geht.
– Krakengrabbus
14. Juni 2012 um 22:49 Uhr
@sarnold danke für den rat! Das war viel einfacher. Ich konnte es perfekt zum Laufen bringen. Ich habe immer noch Zweifel, ob die Wiederherstellung des Std möglich ist, aber Ihre Lösung hat mich aus der Klemme gebracht. Vielen Dank!
– Alessandro Empire
14. Juni 2012 um 22:54 Uhr
#include <unistd.h>
...
int saved_stdout;
...
/* Save current stdout for use later */
saved_stdout = dup(1);
dup2(my_temporary_stdout_fd, 1);
... do some work on your new stdout ...
/* Restore stdout */
dup2(saved_stdout, 1);
close(saved_stdout);
Das hat mir wirklich sehr weitergeholfen. Ich habe mich jedoch gefragt, was die Funktion von close(saved_stdout) ist. Ich habe close zum Schließen von Dateien verwendet, bin aber noch nicht damit vertraut, wie der gesamte Vorgang der Dup-Funktion funktioniert.
– Denken Sie Bonobo
13. April 2014 um 19:22 Uhr
@ThinkBonobo, saved_stdout ist ein Duplikat (also dup()) des ursprünglichen Dateideskriptors für die ursprüngliche Datei, die der Standardausgabe des Programms zugrunde liegt. Wann wird es wieder dupliziert zurück zu (dup2()) stdout (Dateideskriptor Nr. 1) hat das Programm zwei Kopien/Handles/Deskriptoren für dieselbe zugrunde liegende Datei. Dies ist nicht mehr erforderlich, sobald die Ausgabeumleitung abgeschlossen ist (und es könnte Ressourcenbeschränkungen oder Annahmen über Dateisperren usw. durcheinanderbringen), daher ist es eine gute Vorgehensweise, die Ressource zu schließen, wenn sie nicht mehr benötigt wird.
– Pilkrähe
15. April 2014 um 15:44 Uhr
Jonathan Leffler
Bevor Sie das tun dup2(fd, STDOUT_FILENO)sollten Sie den aktuellen offenen Dateideskriptor für die Standardausgabe speichern, indem Sie doing int saved_stdout = dup(STDOUT_FILENO); (vermieten dup() wählen Sie eine verfügbare Dateideskriptornummer für Sie). Nachdem Sie die Ausgabe in eine Datei umgeleitet haben, können Sie dies tun dup2(saved_stdout, STDOUT_FILENO) um die Standardausgabe dort wiederherzustellen, wo sie war, bevor Sie das alles gestartet haben (und Sie sollten schließen saved_stdout zu).
Sie müssen sich um das Leeren von Standard-I/O-Streams kümmern (fflush(stdout)) zu geeigneten Zeiten, während Sie damit herumspielen. Das bedeutet “bevor Sie stdout umschalten”.
Wenn das Programm in einer Linux-Umgebung ausgeführt wird, ist dies möglich freopen ("/dev/stdout", "a", stdout).
Aber wenn man das weiß stdout war das Terminal, freopen ("/dev/tty", "a", stdout) oder das Äquivalent für andere Betriebssysteme – sogar Windows.
Wenn der dup2() funktioniert, /dev/stdout sollte auf die Datei verweisen. Sie haben also die Ausgabe von der Datei auf die Datei umgestellt, glaube ich.
– Jonathan Leffler
14. Juni 2012 um 23:02 Uhr
@JonathanLeffler: Wenn er die ändert fdherum, das wäre wahr. Aus seiner Beschreibung ist bei weitem nicht ersichtlich, was passiert. Es scheint, dass er stattdessen die FILE-Verbindungen ändert.
– Wallyk
14. Juni 2012 um 23:11 Uhr
Da er die Verwendung erwähnt dup2() Um die Standardausgabe umzuschalten, scheint es mir, dass er zunächst mit Dateideskriptoren herumspielt. Der Code zum Zurücksetzen der Dinge in der Frage ist unwiederbringlich seltsam. eine Umschreibung ist angesagt. Aber darum sollen sich die Antworten natürlich drehen.
– Jonathan Leffler
14. Juni 2012 um 23:15 Uhr
13693400cookie-checkC stdout im Terminal wiederherstellenyes
Ich habe das Gefühl, dass ich versuche, mich zu bewegen
stdout
herum so herum ist wahrscheinlich eine schlechte Idee — welche Position sollte das genau haben Terminal melde dich einfgetpos()
? Warum nicht einfach eine Datei öffnen und mit ausgebenfwrite()
oderfprintf()
oderwrite()
und über das Terminal ausgegeben/dev/tty
wenn du es brauchst?– Sarnold
14. Juni 2012 um 22:30 Uhr
@sarnold: wahrscheinlich, weil das Programm Bibliotheken oder anderen unveränderlichen Code hat, mit dem fest verdrahtet ist
stdout
.– Wallyk
14. Juni 2012 um 22:31 Uhr
@sarnold Ich habe eigentlich nicht an diese Möglichkeit gedacht. Lass mich schnell nachsehen.
– Alessandro Empire
14. Juni 2012 um 22:37 Uhr
Ich habe nicht genug Informationen, um eine gute Antwort zu posten, also kommentiere ich stattdessen. Unter Windows können Sie die Konsole erneut anhängen. Ich würde mir jede Win32-SDK-Dokumentation ansehen. Es ist nicht schwer; Ich kann mich nur nicht erinnern, wie es geht.
– Krakengrabbus
14. Juni 2012 um 22:49 Uhr
@sarnold danke für den rat! Das war viel einfacher. Ich konnte es perfekt zum Laufen bringen. Ich habe immer noch Zweifel, ob die Wiederherstellung des Std möglich ist, aber Ihre Lösung hat mich aus der Klemme gebracht. Vielen Dank!
– Alessandro Empire
14. Juni 2012 um 22:54 Uhr