2009-07-28 23 views
2

Der folgende Code endet mit Rohrbruch, wenn sie in T-Shirt aus geleitet, aber korrekt verhalten, wenn nicht verrohrt:Python stdout bündig und Tee

#!/usr/bin/python 
import sys 
def testfun(): 
    while 1: 
     try : 
      s = sys.stdin.readline() 
     except(KeyboardInterrupt) : 
      print('Ctrl-C pressed') 
      sys.stdout.flush() 
      return 
     print s 

if __name__ == "__main__": 
    testfun() 
    sys.exit() 

Erwartete Ausgabe:

./bug.py 
Ctrl-C pressed 

Was beobachtet wird, wenn verrohrt in T-Shirt ist entweder ein Rohrbruch oder keine Ausgabe überhaupt, das heißt nichts auf T-stdout, und nichts in bug.log:

./bug.py | tee bug.log 
Traceback (most recent call last): 
    File "./bug.py", line 14, in <module> 
    sys.stdout.flush() 
IOError: [Errno 32] Broken pipe 

Was kann der Grund dafür sein?

Antwort

3

Wenn Sie Ctrl-C treffen, wird die Schale beide Prozesse (python und tee) und abzureißen das Rohr sie verbindenden beenden.

Also, wenn Sie die Ctrl-C in Ihrem python Prozess und Flush behandeln, wird es feststellen, dass tee wurde beendet und die Rohrleitung ist nicht mehr. Daher die Fehlermeldung.

(Nebenbei bemerkt, würden Sie etwas im Protokoll erwarten? Ich sehe Ihren Prozess nichts ausgibt, anders als die bündig an der Ausfahrt)

+1

Ich erwarte, dass Ctrl-C angezeigten Mann-T gedrückt im Protokoll. – shodanex

+0

Natürlich. Leider wird der 'Tee' Prozess wahrscheinlich bis dahin vorbei sein. Ich würde einfach die Python-Standardausgabe in eine Datei umleiten und dann diese Datei beenden. Abhängig von Ihrer Shell können Sie wahrscheinlich etwas Umständliches tun, um weiterzuleiten und weiterhin auf die Konsole zu schreiben. –

+0

Ah. Ich habe gerade Ihr Named-Pipes-Geschäft unter –

5

Dies ist kein Problem, sondern ein Python-Shell-Problem, als spitze Durch Drücken von Strg-C beendet Brian beide Prozesse. Problemumgehung besteht darin, benannte Pipes zu verwenden:

7

Nein, drücken Strg-C beendet nicht beide Prozesse. Es beendet nur den Tee-Prozess, das Ende des Tee-Prozesses schließen Sie die Pipe zwischen Ihrem Skript und Tee, und damit stirbt Ihr Skript mit der Nachricht unterbrochene Pipe.

Um das zu beheben, hat T-Stück eine Option, das Strg-C in dem vorherigen Prozess in dem Rohr passieren: -i

Versuch:

./bug.py 
^CCtrl-C pressed 
./bug.py | tee log 
^CTraceback (most recent call last): 
    File "./bug.py", line 14, in <module> 
    testfun() 
    File "./bug.py", line 9, in testfun 
    sys.stdout.flush() 
IOError: [Errno 32] Broken pipe 

./bug.py | tee -i log 
^CCtrl-C pressed 
+0

gesehen. Das behebt das Problem für mich, aber ich musste einige sys.stdout.flush() -Aufrufe hinzufügen, die nicht notwendig waren, wenn ich nur zu stdout gehe. –