2017-12-06 2 views
0

Für einen Test möchte ich ein lang laufendes Python 3-Skript unter Linux starten, einige seiner Ausgaben erfassen, prüfen, ob es wie erwartet ist und es wieder beenden.Wie kann ich die Ausgabe eines lang laufenden Python-Subprozesses asynchron erfassen?

Ich versuche nur, das allgemeine Framework für jetzt zu arbeiten.

Wenn ich den folgenden Code ausführen, würde ich erwarten, dass die Ausgabe line = "0" enthalten - das Python-Skript druckt nur eine wachsende Sequenz von ganzen Zahlen, eine pro Sekunde. Stattdessen wird diese for Schleife vollständig übersprungen.

import subprocess 
from tempfile import NamedTemporaryFile 
import time 
import unittest 

import asynchronousfilereader 

class TestProcessSpawning(unittest.TestCase): 
    def test_spawning_counter(self): 
     counter_code = \ 
""" 
import time 
i = 0 
while True: 
    print(i) 
    i = i + 1 
    time.sleep(1) 
""" 

     with NamedTemporaryFile(mode="w", suffix='.py', delete=False)\ 
       as temp_file: 
      temp_file.write(counter_code) 
      file_name = temp_file.name 

      # proc = subprocess.Popen(['ping', 'localhost'], 
      #       stdout=subprocess.PIPE, close_fds=True) 
      proc = subprocess.Popen(['python3', file_name], 
            stdout=subprocess.PIPE, close_fds=True) 

      time.sleep(3) 

      assert proc.returncode is None # None => still running 

      reader = asynchronousfilereader.AsynchronousFileReader(proc.stdout) 

      time.sleep(3) # give it a chance? 

      for line in reader.readlines(): 
       print('line = "{}"'.format(line)) 
       break # just grab first one 

      proc.kill() 

Wenn ich jedoch ['python3', file_name]-['ping', 'localhost'] ich ändern, um eine Zeile der Ausgabe von ping bekommen tun (ich bin auf Linux läuft so hält ping Ausgabe erzeugt bis zum Anschlag).

Eine Idee, warum dies für andere Arten von Subprozess, aber nicht für Python ok zu funktionieren scheint?


Hinweise:

  • dieser Code verwendet die asynchronousfilereader erhältlich von pip
  • wenn ich das Skript nur python3 <temp_file_name> in einer Shell ausgeführt, wie erwartet läuft, Druck 0, 1, 2,. ..
  • der Prozess Rückkehrcode None nach ein paar Sekunden schlägt vor, der Prozess wird ausgeführt (dh stürzt nicht nur)
  • Ich habe versucht, ru nning es durch unbuffer als here vorgeschlagen: die Ausgabe nicht
  • erschien habe ich versucht, bufsize=1 zu Popen vorbei: die Ausgabe nicht
  • erschien, wenn ich die -v Flagge Ich bekomme eine Menge Ausgabe, darunter diese umfassen, die Python schon sagt, versuchen, interaktiv, obwohl ich einen Dateinamen laufen zur Verfügung gestellt habe:

Python 3.5.2 (Standard, 23. November 2017, 16.37.01)

[GCC 5.4.0 20160609] O n linux

Geben Sie "help", "copyright", "credits" oder "license" ein, um weitere Informationen zu erhalten.

+0

Ich aktualisierte das doppelte Ziel. Ihr Problem besteht darin, dass Sie den Ausgabepuffer im Subprozess nicht leeren. Entweder mit dem '-u' Schalter laufen, oder' flush = True' zu ​​deinen 'print()' Anrufen hinzufügen. –

+0

Beachten Sie, dass einige Importe fehlen ('NamedTemporaryFile',' time') und dass die Anweisung 'with ... as' in einer einzelnen Zeile stehen muss. –

+0

@MartijnPieters Ich hatte bereits '-u' probiert und gerade' flush = True' versucht. Ich bekomme immer noch nicht die Ausgabe. Danke, dass du mir von den Importproblemen erzählt hast - ich werde es reparieren. –

Antwort

Verwandte Themen