wake-up-neo.net

IOError Input/Output Error beim Drucken

Ich habe einen Code geerbt, der regelmäßig (zufällig) ausfällt, weil während eines Druckaufrufs ein Eingabe-/Ausgabefehler auftritt. Ich versuche, die Ursache für die Ausnahmebedingung zu ermitteln (oder zumindest besser zu verstehen) und zu ermitteln, wie die Ausnahmebedingung richtig gehandhabt wird.

Beim Ausführen der folgenden Python-Zeile (in einem 2.6.6-Interpreter unter CentOS 5.5):

print >> sys.stderr, 'Unable to do something: %s' % command

Die Ausnahme wird ausgelöst (Traceback weggelassen):

IOError: [Errno 5] Input/output error

Für den Kontext ist dies im Allgemeinen das, was die größere Funktion derzeit versucht:

from subprocess import Popen, PIPE
import sys
def run_commands(commands):
    for command in commands:
        try:
            out, err = Popen(command, Shell=True, stdout=PIPE, stderr=PIPE).communicate()
            print >> sys.stdout, out
            if err:
                raise Exception('ERROR -- an error occurred when executing this command: %s --- err: %s' % (command, err))
        except:
            print >> sys.stderr, 'Unable to do something: %s' % command
run_commands(["ls", "echo foo"])

Die >>-Syntax ist mir nicht besonders vertraut, ich verwende sie nicht oft, und ich verstehe, dass es vielleicht die am wenigsten bevorzugte Art ist, an stderr zu schreiben. Ich glaube jedoch nicht, dass die Alternativen das zugrunde liegende Problem beheben würden.

Aus der Dokumentation, die ich gelesen habe, geht hervor, dass IOError 5 häufig missbraucht und etwas unklar definiert wird und von verschiedenen Betriebssystemen verwendet wird, um unterschiedliche Probleme abzudecken. Das Beste, was ich in meinem Fall sehen kann, ist, dass der Python-Prozess nicht mehr mit dem Terminal/pty verbunden ist.

Wie ich am besten beurteilen kann, trennt nichts den Prozess von den Streams stdout/stderr - das Terminal ist beispielsweise noch geöffnet und alles scheint in Ordnung zu sein. Könnte es daran liegen, dass der untergeordnete Prozess auf unreine Weise beendet wird? Was könnte sonst eine Ursache für dieses Problem sein - oder welche anderen Schritte könnte ich einleiten, um es weiter zu debuggen?

In Bezug auf die Behandlung der Ausnahme kann ich sie natürlich abfangen, aber ich gehe davon aus, dass ich für den Rest der Ausführung nicht auf stdout/stderr drucken kann. Kann ich irgendwie eine erneute Verbindung zu diesen Streams herstellen - möglicherweise durch Zurücksetzen von sys.stdout auf sys.__stdout__ usw.? In diesem Fall ist es nicht fatal, nicht in stdout/stderr schreiben zu können, aber wenn es ein Hinweis darauf ist, dass etwas schief geht, würde ich es vorziehen, vorzeitig auf Kaution zu gehen.

Ich denke, letztendlich bin ich ein bisschen ratlos, wo ich anfangen soll, dieses zu debuggen ...

20

Ich denke, es hat mit dem Terminal zu tun, an das der Prozess angebunden ist. Ich habe diese Fehlermeldung erhalten, als ich im Hintergrund einen Python-Prozess ausführte und das Terminal, in dem ich es gestartet habe, geschlossen habe:

$ myprogram.py
Ctrl-Z
$ bg
$ exit

Das Problem war, dass ich einen nicht daemonisierten Prozess auf einem Remote-Server gestartet und mich abgemeldet habe (Schließen der Terminalsitzung). Eine Lösung bestand darin, eine screen/tmux-Sitzung auf dem Remote-Server zu starten und den Prozess innerhalb dieser Sitzung zu starten. Beim Trennen der Sitzung + Abmelden bleibt das mit dem Prozess verbundene Terminal erhalten. Dies funktioniert zumindest in der * nix-Welt.

12
jmkg

Ich hatte ein sehr ähnliches Problem. Ich hatte ein Programm, das mehrere andere Programme mit dem Subprozess-Modul startete. Diese Unterprozesse würden dann die Ausgabe an das Terminal drucken. Ich fand heraus, dass beim Schließen des Hauptprogramms die Teilprozesse nicht automatisch beendet wurden (wie ich angenommen hatte), sondern sie liefen weiter. Wenn ich also sowohl das Hauptprogramm als auch das von * gestartete Terminal beendet habe, hatten die Unterprozesse kein Terminal mehr an ihrem Standardausgang angeschlossen und würden einen IOError werfen. Hoffe das hilft dir.

* NB: es muss in dieser Reihenfolge gemacht werden. Wenn Sie nur das Terminal töten (aus irgendeinem Grund), würde dies sowohl das Hauptprogramm als auch die Unterprozesse beenden.

6
gtg944q

Ich habe gerade diese Fehlermeldung erhalten, weil das Verzeichnis, in das ich Dateien geschrieben habe, nicht genügend Speicherplatz hatte. Nicht sicher, ob dies für Ihre Situation überhaupt gilt.

2
zss

Ich bin neu hier, also bitte verzeihen Sie, wenn ich beim Code-Detail ein wenig nachlasse. Vor kurzem konnte ich herausfinden, was den I/O-Fehler der print-Anweisung verursacht, wenn das Terminal verbunden ist Mit dem Lauf des Python-Skripts wird geschlossen. Dies ist darauf zurückzuführen, dass die zu stdout/stderr zu druckende Zeichenfolge zu lang ist. In diesem Fall ist die Zeichenfolge "out" der Schuldige. Um dieses Problem zu beheben (ohne das Terminal beim Ausführen des Python-Skripts geöffnet zu lassen), lesen Sie einfach die Zeichenfolge "out" Zeile für Zeile und drucken Sie Zeile für Zeile, bis wir das Ende der Zeichenfolge "out" erreichen. So etwas wie:

while true:
        ln=out.readline()
        if not ln: break
        print ln.strip("\n") # print without new line

Dasselbe Problem tritt auf, wenn Sie die gesamte Liste der Zeichenfolgen auf dem Bildschirm ausdrucken. Drucken Sie die Liste einfach einzeln aus. Ich hoffe, das hilft!

1
Thang

Dies kann passieren, wenn Ihre Shell abstürzt, während der Druck versucht, die Daten in die Shell zu schreiben.

0
mtmt