2012-08-03 9 views
9

Jedesmal, wenn ich bin mein Python-Skript ausgeführt wird, es auf dieser Linie zu hängen scheint:sys.stdin.readlines() hängt Python-Skript

lines = sys.stdin.readlines() 

Was soll ich tun, um zu beheben/dies vermeiden?

EDIT

Hier ist, was ich mit lines mache:

lines = sys.stdin.readlines() 
updates = [line.split() for line in lines] 

EDIT 2

ich dieses Skript von einem git Haken renne so ist es trotzdem, um der EOF?

+0

Beachten Sie, dass readlines() ein EOF erfordert, bevor es zurückkehrt. Dies geschieht erst, wenn der stdin über die ausführende Anwendung/Shell ein EOF gegeben wird. –

Antwort

13

Dies hängt sehr davon ab, was Sie erreichen möchten. Möglicherweise können do sein:

for line in sys.stdin: 
    #do something with line 

Natürlich mit diesem Idiom sowie die readlines() Methode, die Sie verwenden, müssen Sie die EOF-Zeichen an das Skript irgendwie schicken, damit er weiß, dass die Datei zu bereit ist, lesen. (Bei Unix funktioniert Ctrl-D normalerweise).

+0

@JasonMock - Ja, das merke ich (weshalb ich sage "damit es weiß, dass die Datei gelesen wird"). – mgilson

+0

Ich führe dieses Skript von einem Git-Hook aus, also gibt es eh um den EOF herum? –

+0

@BoA - Sorry, ich weiß nichts über Git-Hooks, obwohl es scheint, dass wenn dein Programm von einer Pipe liest, es einfach funktionieren sollte. – mgilson

5

Es sei denn, Sie umleiten etwas an stdin, dass Verhalten erwartet würde. Das sagt, um die Eingabe von stdin zu lesen (das wäre die Konsole, von der das Skript ausgeführt wird). Es wartet auf Ihre Eingabe.

See: "How to finish sys.stdin.readlines() input?

2

Wenn Sie das Programm in einer interaktiven Sitzung laufen lassen, dann ist diese Zeile Python verursacht von der Standardeingabe (dh der Tastatur) zu lesen, bis Sie die EOF-Zeichen (Ctrl senden - D (Unix/Mac) oder Strg - Z (Windows)).

>>> import sys 
>>> a = sys.stdin.readlines() 
Test 
Test2 
^Z 
>>> a 
['Test\n', 'Test2\n'] 
3

Ich weiß, das ist nicht direkt Ihre Frage zu beantworten, wie andere haben bereits die EOF Problem adressiert, aber in der Regel, was ich gefunden habe, das am besten funktioniert, wenn Live-Ausgabe von einem lang lebte subprocess oder stdin lesen Während ist/if Linie Ansatz:

while True: 
    line = sys.stdin.readline() 
    if not line: 
     break 
    process(line) 

In diesem Fall sys.stdin.readline() werden Textzeilen zurückkehren vor ein EOF zurückgegeben. Sobald der EOF gegeben ist, wird die leere Zeile zurückgegeben, die die Unterbrechung von der Schleife auslöst. Ein Hang kann immer noch hier auftreten, solange kein EOF zur Verfügung gestellt wird.

Es ist erwähnenswert, dass die Fähigkeit, die "Live-Ausgabe" zu verarbeiten, während der Subprozess/stdin noch läuft, erfordert, dass die Schreibanwendung ihre Ausgabe spült.

+1

Ich denke @ mgilson's Antwort würde besser funktionieren; das würde funktionieren, aber es ist der mehr "Pythonic" Weg – pbfy0

+0

Ich stimme völlig mit der Aussage überein, dass @ mgilson's Antwort mehr pythisch ist. Ich habe es nur nicht als sehr freundlich für "Live-Ausgabe" empfunden, zum Beispiel das Erfassen von Statusinformationen von einer lang laufenden Anwendung, um den Status an den Benutzer zurückzumelden, da das Datei-ähnliche Objekt ein EOF erzeugen muss, bevor die Schleife beginnt wird bearbeitet. In meinem Beispiel wird der Aufruf von readline() mir Textzeilen geben, bevor ein EOF zurückgegeben wird. Das EOF muss nur von der while getrennt werden, indem man mir eine Leerzeile gibt. Davon abgesehen, könnte ich meine Beschreibung wahrscheinlich verbessern, weil das nicht sehr klar ist. –

+0

Es läuft Line-by-Line für mich auf Linux ... – pbfy0