2009-10-12 17 views
8

Duplicar posibles:
subprocess with timeoutpitón: ejecutar un proceso con tiempo de espera y la salida estándar de captura, stderr y estado de salida

¿Cuál es la manera más fácil de hacer lo siguiente en Python:

  • Ejecutar un proceso externo
  • Capturar stdout en una cadena, stderr y salir del estado
  • Establecer un tiempo de espera.

me gustaría algo como esto:

import proc 

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

Sólo para que nosotros sabemos de dónde vas a empezar a partir, ¿ha considerado el módulo 'subprocess'? http://docs.python.org/library/subprocess.html –

+0

no, parece que es un gran salto adelante – flybywire

+1

subproceso 'Popen.communicate with timeout, pregunta similar: http://stackoverflow.com/questions/1191374/ subproceso-con-tiempo de espera – Mark

Respuesta

12

odio hacer el trabajo por mí mismo. Simplemente copie esto en su módulo proc.py.

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

Esta versión podría expirar debido al desbordamiento del búfer de la tubería (cuando stdout o stderr ~ 64K). – jfs

+1

Si el comando expira, no obtendrá ningún resultado generado hasta el tiempo de espera. –

+0

tirada de impresión (["ping www.redicecn.com"], timeout = 10), la secuencia de comandos arrojó la excepción de Tiempo de espera, pero el proceso de ping aún se estaba ejecutando. – redice

11

Nota sobre Linux con coreutils> = 7.0 puede anteponer tiempo de espera a la orden como:

timeout 1 sleep 1000 
Cuestiones relacionadas