2009-10-12 2 views
8

Mögliche Duplizieren:
subprocess with timeoutPython: einen Prozess mit Timeout und Capture stdout laufen, stderr und Exit-Status

Was der einfachste Weg ist es, die folgenden in Python zu tun:

  • Einen externen Prozess ausführen
  • Capture stdout in einem String, stderr und Exit-Status
  • Legen Sie eine Zeitüberschreitung fest.

würde ich so etwas wie dies mag:

import proc 

try: 
    status, stdout, stderr = proc.run(["ls", "-l"], timeout=10) 
except proc.Timeout: 
    print "failed" 
+2

Nur so wissen wir, von wo Sie beginnen, haben Sie als das 'subprocess' Modul? http://docs.python.org/library/subprocess.html –

+0

nein - sieht so aus ist das ein großer Sprung vorwärts – flybywire

+1

Subprozess 'Popen.communicate mit Timeout, ähnliche Frage: http://StackOverflow.com/Questions/1191374/ Subprozess-mit-Timeout – Mark

Antwort

12

ich mir die Arbeit hassen zu tun. Kopieren Sie dies einfach in Ihr proc.py-Modul.

import subprocess 
import time 
import sys 

class Timeout(Exception): 
    pass 

def run(command, timeout=10): 
    proc = subprocess.Popen(command, bufsize=0, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
    poll_seconds = .250 
    deadline = time.time()+timeout 
    while time.time() < deadline and proc.poll() == None: 
     time.sleep(poll_seconds) 

    if proc.poll() == None: 
     if float(sys.version[:3]) >= 2.6: 
      proc.terminate() 
     raise Timeout() 

    stdout, stderr = proc.communicate() 
    return stdout, stderr, proc.returncode 

if __name__=="__main__": 
    print run(["ls", "-l"]) 
    print run(["find", "/"], timeout=3) #should timeout 
+1

Diese Version könnte aufgrund eines Pipe-Pufferüberlaufs einen Timeout haben (wenn stdout oder stderr ~ 64K). – jfs

+1

Wenn der Befehl abläuft, erhalten Sie keine Ausgabe, die bis zum Timeout generiert wird. –

+0

Drucklauf (["ping www.redicecn.com"], Timeout = 10), das Skript hat eine Timeout-Ausnahme ausgelöst, aber der Ping-Prozess wurde noch ausgeführt. – redice

11

Hinweis auf Linux mit coreutils> = 7.0 Sie Timeout auf den Befehl wie voranstellen können:

timeout 1 sleep 1000 
Verwandte Themen