C stdout im Terminal wiederherstellen

Lesezeit: 4 Minuten

Benutzer-Avatar
Alessandro Empire

Ich arbeite mit einem Multithread-Programm.

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.

Mein erster Ansatz:

      /*Declaration*/
      fpost_t  stream_sdout;
      /*code*/
      if ( fgetpos( stdout, &stream_sdout) == -1 )
          perror(Error:);

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

Benutzer-Avatar
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

1369340cookie-checkC stdout im Terminal wiederherstellen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy