Frage

Dies ist eine Follow -up -Frage von hier speziell in Bezug auf seine Antworten.


Aus einem Python -Modul nenne ich a Hallo Welt ausführbare Datei, die einfach druckt Hello World zum Stdout. Ich bin daran interessiert, diese Ausgabe in einen Python umzulenken StringIO und rannte in Dies Antwort, die mich fast bis zur Lösung bringt.

Der kritische Teil dieser Antwort ist dieses Codesegment:

1. def redirect_stdout():
2.     print "Redirecting stdout"
3.     sys.stdout.flush() # <--- important when redirecting to files
4.     newstdout = os.dup(1)
5.     devnull = os.open('/dev/null', os.O_WRONLY)
6.     os.dup2(devnull, 1)
7.     os.close(devnull)
8.     sys.stdout = os.fdopen(newstdout, 'w')

Außerdem möchte ich den Stdout wie vor der Umleitung wiederherstellen.

Fragen

  1. Was genau ist in der obigen Funktion los?
    • Was ist dup und dup2 tun?
    • Was ist /dev/null?
    • Was macht Zeile 8? (sys.stdout = os.fdopen(newstdout, 'w'))
  2. Wie kann ich den Stdout in einem aufbewahren? StringIO Objekt?
  3. Wie kann ich den Stdout nach dem Anruf an meinen wiederherstellen? Hallo Welt Programm?

Ich bin mir ziemlich sicher, dass ich, sobald ich die Antwort auf meine Frage 1 habe, dass die Antworten von Fragen 2 und 3 einfach sind. Ich beschloss, sie trotzdem zu posten, um die Antwort von Frage 1 in die Richtung zu bringen, in die ich gehen möchte.

War es hilfreich?

Lösung

Ich habe unten ein paar zusätzliche Kommentare geschrieben, die klarer machen sollten, was es im Inneren im Vorgang ist redirect_stdout Funktion:

def redirect_stdout():
    print "Redirecting stdout"
    sys.stdout.flush() # <--- important when redirecting to files

    # Duplicate stdout (file descriptor 1)
    # to a different file descriptor number
    newstdout = os.dup(1)

    # /dev/null is used just to discard what is being printed
    devnull = os.open('/dev/null', os.O_WRONLY)

    # Duplicate the file descriptor for /dev/null
    # and overwrite the value for stdout (file descriptor 1)
    os.dup2(devnull, 1)

    # Close devnull after duplication (no longer needed)
    os.close(devnull)

    # Use the original stdout to still be able
    # to print to stdout within python
    sys.stdout = os.fdopen(newstdout, 'w')

Eine wichtige Sache ist zu beachten, dass ein Prozess drei verschiedene wird Dateideskriptoren Aus dem Betriebssystem beim Start:

  • stdin: 0
  • Stdout: 1
  • Stderr: 2

Wie in den Kommentaren erläutert, nutzt der obige Code den Dateideskriptor für STDOut und die Dateideskriptor -Duplikationsfunktionen, um den C -Code dazu zu bringen zu drucken.

Andere Tipps

/dev/null ist eine spezielle Gerätedatei (alles in Unix ist eine Datei!), Die alles wie ein Schwarzes Loch schluckt. dup Dupliziert einen Dateideskriptor. Wenn Sie an Windows gewöhnt sind, ist ein Dateideskriptor in UNIX eine spezielle Ganzzahl, die eine geöffnete Datei darstellt.

Das Programm wird geöffnet /dev/null Für das Schreiben (nur), die eine Kopie des Dateideskriptors übernehmen, die offene Datei schließen (da ein Dateideskriptor ausreicht, um in eine Datei zu schreiben, müssen Sie die Ressourcen nicht geöffnet halten) und dann das Öffnen zuzuweisen Datei an sys.stdout.

Denken Sie daran sys ist das Python-Modul, das alle Arten von systemspezifischen Ressourcen wie das Dateisystem darstellt. Also in Unix sys.stdout wird darstellen /dev/stdout dh das System STDOUT Strom.

Insgesamt täuscht dieser Code Python, das zu denken, das /dev/null/ ist STDOUT Also jetzt jedes Mal, wenn Ihr Programm schreibt STDOUT mit beispielsweise die print Aussage (Funktion in Python3) dann wird sie wirklich schreiben /dev/null Und Sie werden den resultierenden Text auf Ihrer Konsole niemals sehen.

Sehen Handbuchseiten Für die C -Laufzeitfunktionen, die diesen Python -Funktionen zugrunde liegen.

Grundsätzlich duplizieren sie einen Dateideskriptor in einen neuen Dateideskriptor (mit dup()) oder in einen im Anruf angegebenen Dateideskriptor mit mit dup2().

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top